Page 1 of 1

no pixels defined in cache

Posted: 2012-05-25T17:08:42-07:00
by steved
I built a Linux binary from the IM 6.7.7-0 source tree. I observed the result from configure that jpeg was included. I load the MagickWand library in Java using JNA and try to read a jpeg image. I get the following error:

no pixels defined in cache `/home/steved/Imgc/unreadable.jpg' @ error/cache.c/OpenPixelCache/3992

I also installed a prebuilt Linux binary of IM 6.6.9-7, and using the display command I can view the image, so I know IM can process it.

Any idea what I need to do to configure or build IM correctly, or at least well enough to read my file?

Re: no pixels defined in cache

Posted: 2012-05-30T08:49:00-07:00
by steved
The error seems to be happening because either the image columns or rows is 0. It happens in cache.c at this line (3992)

if ((image->columns == 0) || (image->rows == 0))
ThrowBinaryException(CacheError,"NoPixelsDefinedInCache",image->filename);

This happens after writeimages completes properly and the transformed image file is written out. So, (1) why do the pixels need to be cached when I am done with them and (2) how did the image dimensions get clobbered? Does anyone have any debugging suggestions?

Re: no pixels defined in cache

Posted: 2012-05-30T17:14:04-07:00
by steved
I've tracked the issue down.

When I do a MagickReadImage, I can see the exception thrown, but then if I immediately do a MagickGetException, the Exception returned is 0. Then I do a bunch of misc. manipulations. Then I do another MagickGetException (getting a 0 back), a MagickWriteImages that returns success as well as actually writes the image file, and then another MagickGetException that returns an error, 445 (NoPixelsDefinedInCache).

I figured this out by putting printf statements in cache.c and by writing a C program that did the same calls as my Java program did. The C program is available if someone wants to use it to duplicate the issue.

Re: no pixels defined in cache

Posted: 2012-05-31T04:15:11-07:00
by magick
Post a small program that illustrates the problem so we can download and reproduce the problem. Once we do we'll let you know if its a bug or logic error.

Re: no pixels defined in cache

Posted: 2012-05-31T09:21:57-07:00
by steved
Here's the test program:

Code: Select all

// Last updated 2008/11/04 10:53

// convert logo: -filter lanczos -resize 50% -quality 95 logo_resize.jpg
// Read an image, resize it by 50% and sharpen it, and then save as
// a high quality JPG
// Note that ImageMagick's default quality is 75.

//#include <windows.h>
#include <wand/magick_wand.h>

void test_wand(void)
{
	MagickWand *m_wand = NULL;
	
	int width,height;
	
	MagickWandGenesis();
	
	m_wand = NewMagickWand();
	// Read the image - all you need to do is change "logo:" to some other
	// filename to have this resize and, if necessary, convert a different file
	printf("about to read image\n");
	MagickReadImage(m_wand,"test.jpg");
	printf("image read\n");

	// SJD
	ExceptionType  exception = (ExceptionType)0;
	char *dsc = MagickGetException(m_wand, &exception);
	printf("exception=%d\n", exception);
        MagickRelinquishMemory((void *)dsc);

	const char *fmt = MagickGetImageFormat(m_wand);
        MagickRelinquishMemory((void *)fmt);
	MagickResetIterator(m_wand);
       size_t n = MagickGetNumberImages(m_wand);
        MagickNextImage(m_wand);
        
	// Get the image's width and height
	width = MagickGetImageWidth(m_wand);
	height = MagickGetImageHeight(m_wand);
	
	// Cut them in half but make sure they don't underflow
	if((width /= 2) < 1)width = 1;
	if((height /= 2) < 1)height = 1;
	
	// SJD
	fmt = MagickGetImageFormat(m_wand);
        MagickRelinquishMemory((void *)fmt);
        MagickStripImage(m_wand);

	// Resize the image using the Lanczos filter
	// The blur factor is a "double", where > 1 is blurry, < 1 is sharp
	// I haven't figured out how you would change the blur parameter of MagickResizeImage
	// on the command line so I have set it to its default of one.
	// MagickResizeImage(m_wand,width,height,LanczosFilter,1);

	// SJD
        MagickScaleImage(m_wand, width, height);
	MagickNextImage(m_wand);
        MagickSetIteratorIndex(m_wand, 0);

	// Set the compression quality to 95 (high quality = low compression)
	MagickSetImageCompressionQuality(m_wand,75);
	dsc = MagickGetException(m_wand, &exception);
	printf("exception=%d\n", exception);
        MagickRelinquishMemory((void *)dsc);
	
	/* Write the new image */
	int success = MagickWriteImages(m_wand,"resize.jpg", 1);

	// SJD
	printf("success=%d\n", success);
	dsc = MagickGetException(m_wand, &exception);
	printf("exception=%d\n", exception);
        MagickRelinquishMemory((void *)dsc);
	
	/* Clean up */
	if(m_wand)m_wand = DestroyMagickWand(m_wand);
	
	MagickWandTerminus();
}

int main(int argc, char** argv) {
    test_wand();
}
The code is complicated because I duplicated all the steps found in the larger Java program. The output from the program is:

Code: Select all

about to read image
GIPC2  test.jpg: columns=0, rows=0
OPC  test.jpg: columns=0, rows=0
OPC fail!  test.jpg: columns=0, rows=0
GIPC2  test.jpg: columns=651, rows=759
OPC  test.jpg: columns=651, rows=759
image read
exception=0
GIPC2  test.jpg: columns=325, rows=379
OPC  test.jpg: columns=325, rows=379
exception=0
success=1
exception=445
You'll see I put printfs in cache.c. The diff follows:

Code: Select all

@@ -2060,6 +2060,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
           clone_image.reference_count=1;
           clone_image.cache=ClonePixelCache(cache_info);
           clone_info=(CacheInfo *) clone_image.cache;
+    fprintf(stderr, "GIPC1  %s: columns=%d, rows=%d\n", image->filename, image->columns, image->rows);
           status=OpenPixelCache(&clone_image,IOMode,exception);
           if (status != MagickFalse)
             {
@@ -2088,6 +2089,7 @@ static Cache GetImagePixelCache(Image *image,const MagickBooleanType clone,
       image->type=UndefinedType;
       if (ValidatePixelCacheMorphology(image) == MagickFalse)
         {
+    fprintf(stderr, "GIPC2  %s: columns=%d, rows=%d\n", image->filename, image->columns, image->rows);
           status=OpenPixelCache(image,IOMode,exception);
           cache_info=(CacheInfo *) image->cache;
           if (cache_info->type == DiskCache)
@@ -3984,12 +3986,15 @@ static MagickBooleanType OpenPixelCache(Image *image,const MapMode mode,
     packet_size;
 
   assert(image != (const Image *) NULL);
+    fprintf(stderr, "OPC  %s: columns=%d, rows=%d\n", image->filename, image->columns, image->rows);
   assert(image->signature == MagickSignature);
   assert(image->cache != (Cache) NULL);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  if ((image->columns == 0) || (image->rows == 0))
+  if ((image->columns == 0) || (image->rows == 0)) {
+    fprintf(stderr, "OPC fail!  %s: columns=%d, rows=%d\n", image->filename, image->columns, image->rows);
     ThrowBinaryException(CacheError,"NoPixelsDefinedInCache",image->filename);
+  }
   cache_info=(CacheInfo *) image->cache;
   assert(cache_info->signature == MagickSignature);
   source_info=(*cache_info);
@@ -4246,6 +4251,7 @@ MagickExport MagickBooleanType PersistPixelCache(Image *image,
         MaxTextExtent);
       cache_info->type=DiskCache;
       cache_info->offset=(*offset);
+    fprintf(stderr, "PPC1  %s: columns=%d, rows=%d\n", image->filename, image->columns, image->rows);
       if (OpenPixelCache(image,ReadMode,exception) == MagickFalse)
         return(MagickFalse);
       *offset+=cache_info->length+page_size-(cache_info->length % page_size);
@@ -4293,6 +4299,7 @@ MagickExport MagickBooleanType PersistPixelCache(Image *image,
   cache_info->type=DiskCache;
   cache_info->offset=(*offset);
   cache_info=(CacheInfo *) image->cache;
+    fprintf(stderr, "PPC2  %s: columns=%d, rows=%d\n", image->filename, image->columns, image->rows);
   status=OpenPixelCache(image,IOMode,exception);
   if (status != MagickFalse)
     status=ClonePixelCachePixels(cache_info,clone_info,&image->exception);
diff --git a/magick/magick-config.h b/magick/magick-config.h
index f484034..46de51b 100644
--- a/magick/magick-config.h
+++ b/magick/magick-config.h
@@ -12,7 +12,9 @@
 /* #undef AUTOTRACE_DELEGATE */

Re: no pixels defined in cache

Posted: 2012-05-31T09:29:11-07:00
by magick
We ran your program with success, no exceptions were thrown. We're using ImageMagick-6.7.7-5, the current release of ImageMagick. Try 6.7.7-5 and if it still fails, let us know.

Put a printf() in your code to print the number of images read. It should return 1. That's another sanity check to ensure the image is read properly.

Re: no pixels defined in cache

Posted: 2012-05-31T10:37:08-07:00
by steved
The problem is indeed gone in 6.7.7-5. Do you care to speculate what the issue was? In any case, thanks for the quick response.

Re: no pixels defined in cache

Posted: 2019-01-17T07:21:02-07:00
by ltqsoft
This error has come back in version 7.0.8-23 when I build with VS 2017 community in C++. The error only occurs with the TGA format, others seem to be OK.

Re: no pixels defined in cache

Posted: 2019-03-11T21:06:10-07:00
by chocomix
I think it may be a cache error has happened to me before