no pixels defined in cache

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
steved
Posts: 5
Joined: 2012-05-25T16:59:29-07:00
Authentication code: 13

no pixels defined in cache

Post 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?
steved
Posts: 5
Joined: 2012-05-25T16:59:29-07:00
Authentication code: 13

Re: no pixels defined in cache

Post 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?
steved
Posts: 5
Joined: 2012-05-25T16:59:29-07:00
Authentication code: 13

Re: no pixels defined in cache

Post 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.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: no pixels defined in cache

Post 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.
steved
Posts: 5
Joined: 2012-05-25T16:59:29-07:00
Authentication code: 13

Re: no pixels defined in cache

Post 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 */
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: no pixels defined in cache

Post 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.
steved
Posts: 5
Joined: 2012-05-25T16:59:29-07:00
Authentication code: 13

Re: no pixels defined in cache

Post 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.
ltqsoft
Posts: 1
Joined: 2019-01-17T07:16:38-07:00
Authentication code: 1152

Re: no pixels defined in cache

Post 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.
chocomix
Posts: 1
Joined: 2019-03-11T20:51:04-07:00
Authentication code: 1152

Re: no pixels defined in cache

Post by chocomix »

I think it may be a cache error has happened to me before
Post Reply