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?
no pixels defined in cache
Re: no pixels defined in cache
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?
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
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.
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
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
Here's the test program:
The code is complicated because I duplicated all the steps found in the larger Java program. The output from the program is:
You'll see I put printfs in cache.c. The diff follows:
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();
}
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
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
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.
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
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
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
I think it may be a cache error has happened to me before