ImageToFile - what is it supposed to do exactly?
Posted: 2014-05-01T16:21:37-07:00
I've been working on this problem where I"m handed some CCITT Group 4 compressed image data with the other metadata needed to define an image.
I've managed to get the blob into ImageMagick to hopefully process things and convert the image to other formats internally (not to have ImageMagick write to files), BUT as intermediate step and to validate that I've got a valid ImageMagick image object, I wanted to write out the image I had stored in ImageMagick.
How that is done isn't obvious. (to me). From the docs http://www.imagemagick.org/api/blob.php
BlobToImage
BlobToImage() implements direct to memory image formats. It returns the blob as an image.
This I have used to get my TIFF blob into an ImageMagic image
Now that same C API page also lists the function:
ImageToFile
ImageToFile() writes an image to a file. It returns MagickFalse if an error occurs otherwise MagickTrue.
Which, based on the terminology would take the image I now have and write it out to a file I specify.
But what does it do? No, it does not.
Taking the TIFF blob that ImageMagic converted via BlobToImage just fine, and trying to write it to file via ImageToFile( myImageMagickImage, "magick.tiff", myImageMagickException) causes a run-time fault - ImageMagic stops at an assert:
assert(image->blob->type != UndefinedStream);
Indeed while the ImageMagick image is defined:
the embedded blob information did indeed have an an undefined stream type:
Um, ok, so what is up with that?
What is ImageToFile supposed to do? The core API's documentation is rather simple and doesn't indicate there would be any issue with this not performing as expected.
I did find another post on this website forum system saying to not use ImageToFile, but rather use WriteImage(imgMagickInfo, imgMagickImage);
Well, that does work as expected.
So now my question remains: what is the difference between the two, and note that ImageToFile is rather misleading in that section of the docs.
http://www.imagemagick.org/api/blob.php#ImageToFile.
ImageToFile
ImageToFile() writes an image to a file. It returns MagickFalse if an error occurs otherwise MagickTrue.
http://www.imagemagick.org/api/constitu ... WriteImage
WriteImage
WriteImage() writes an image or an image sequence to a file or file handle. If writing to a file is on disk, the name is defined by the filename member of the image structure. WriteImage() returns MagickFalse is there is a memory shortage or if the image cannot be written. Check the exception member of image to determine the cause for any failure.
Both indicate they write the image to a file.
My logical issue with what ever ImageToFile does is that it does NOT behave like ImageToBlob, except rather than to a blog it outputs to a file. And that is really confusing (beyond not knowing what ImageToFile is supposed to be used for).
For example, the following succesfully converts my TIFF blob, that was brought in as a TIFF image, into a PNG blob:
I've managed to get the blob into ImageMagick to hopefully process things and convert the image to other formats internally (not to have ImageMagick write to files), BUT as intermediate step and to validate that I've got a valid ImageMagick image object, I wanted to write out the image I had stored in ImageMagick.
How that is done isn't obvious. (to me). From the docs http://www.imagemagick.org/api/blob.php
BlobToImage
BlobToImage() implements direct to memory image formats. It returns the blob as an image.
This I have used to get my TIFF blob into an ImageMagic image
Now that same C API page also lists the function:
ImageToFile
ImageToFile() writes an image to a file. It returns MagickFalse if an error occurs otherwise MagickTrue.
Which, based on the terminology would take the image I now have and write it out to a file I specify.
But what does it do? No, it does not.
Taking the TIFF blob that ImageMagic converted via BlobToImage just fine, and trying to write it to file via ImageToFile( myImageMagickImage, "magick.tiff", myImageMagickException) causes a run-time fault - ImageMagic stops at an assert:
assert(image->blob->type != UndefinedStream);
Indeed while the ImageMagick image is defined:
Code: Select all
- image 0x0096cd68 {storage_class=DirectClass colorspace=GRAYColorspace compression=Group4Compression ...} _Image *
storage_class DirectClass ClassType
colorspace GRAYColorspace ColorspaceType
compression Group4Compression CompressionType
quality 0 unsigned int
orientation TopLeftOrientation OrientationType
taint MagickFalse MagickBooleanType
matte MagickFalse MagickBooleanType
columns 240 unsigned int
rows 210 unsigned int
depth 1 unsigned int
colors 0 unsigned int
+ colormap 0x00000000 {blue=??? green=??? red=??? ...} _PixelPacket *
+ background_color {blue=65535 green=65535 red=65535 ...} _PixelPacket
+ border_color {blue=57311 green=57311 red=57311 ...} _PixelPacket
+ matte_color {blue=48573 green=48573 red=48573 ...} _PixelPacket
gamma 0.45454545454545453 double
+ chromaticity {red_primary={...} green_primary={...} blue_primary={...} ...} _ChromaticityInfo
rendering_intent UndefinedIntent RenderingIntent
profiles 0x00000000 void *
units PixelsPerInchResolution ResolutionType
+ montage 0x00000000 <Bad Ptr> char *
+ directory 0x00000000 <Bad Ptr> char *
+ geometry 0x00000000 <Bad Ptr> char *
offset 0 long
x_resolution 100.00000000000000 double
y_resolution 100.00000000000000 double
+ page {width=240 height=210 x=0 ...} _RectangleInfo
+ extract_info {width=0 height=0 x=0 ...} _RectangleInfo
+ tile_info {width=0 height=0 x=0 ...} _RectangleInfo
bias 0.00000000000000000 double
blur 1.0000000000000000 double
fuzz 0.00000000000000000 double
filter UndefinedFilter FilterTypes
interlace NoInterlace InterlaceType
endian MSBEndian EndianType
gravity UndefinedGravity GravityType
compose OverCompositeOp CompositeOperator
dispose UnrecognizedDispose DisposeType
+ clip_mask 0x00000000 {storage_class=??? colorspace=??? compression=??? ...} _Image *
scene 0 unsigned int
delay 0 unsigned int
ticks_per_second 100 long
iterations 0 unsigned int
total_colors 0 unsigned int
start_loop 0 long
+ error {mean_error_per_pixel=0.00000000000000000 normalized_mean_error=0.00000000000000000 normalized_maximum_error=0.00000000000000000 } _ErrorInfo
+ timer {user={...} elapsed={...} state=RunningTimerState ...} _TimerInfo
progress_monitor 0x00000000 MagickBooleanType (const char *, const __int64, const const unsigned __int64, const void *)*
client_data 0x00000000 void *
cache 0x00970030 void *
attributes 0x00000000 void *
+ ascii85 0x00000000 {offset=??? line_break=??? buffer=0x00000008 <Bad Ptr> } _Ascii85Info *
+ blob 0x00972510 {length=0 extent=1074 quantum=65541 ...} _BlobInfo *
+ filename 0x0096cf30 "" char [4096]
+ magick_filename 0x0096df30 "" char [4096]
+ magick 0x0096ef30 "TIFF" char [4096]
magick_columns 240 unsigned int
magick_rows 210 unsigned int
+ exception {severity=UndefinedException error_number=0 reason=0x00000000 <Bad Ptr> ...} _ExceptionInfo
debug MagickFalse MagickBooleanType
reference_count 1 volatile long
+ semaphore 0x009726c0 {mutex={...} id=20036 reference_count=0 ...} SemaphoreInfo *
+ color_profile {name=0x00000000 <Bad Ptr> length=0 info=0x00000000 <Bad Ptr> ...} _ProfileInfo
+ iptc_profile {name=0x00000000 <Bad Ptr> length=0 info=0x00000000 <Bad Ptr> ...} _ProfileInfo
+ generic_profile 0x00000000 {name=??? length=??? info=??? ...} _ProfileInfo *
generic_profiles 0 unsigned int
signature 2880220587 unsigned int
+ previous 0x00000000 {storage_class=??? colorspace=??? compression=??? ...} _Image *
+ list 0x00000000 {storage_class=??? colorspace=??? compression=??? ...} _Image *
+ next 0x00000000 {storage_class=??? colorspace=??? compression=??? ...} _Image *
interpolate UndefinedInterpolatePixel InterpolatePixelMethod
black_point_compensation MagickFalse MagickBooleanType
+ transparent_color {blue=0 green=0 red=0 ...} _PixelPacket
+ mask 0x00000000 {storage_class=??? colorspace=??? compression=??? ...} _Image *
+ tile_offset {width=0 height=0 x=0 ...} _RectangleInfo
properties 0x00972ea0 void *
artifacts 0x00000000 void *
type BilevelType ImageType
dither MagickTrue MagickBooleanType
extent 1074 unsigned __int64
ping MagickFalse MagickBooleanType
channels 0 unsigned int
timestamp 1398985982 __int64
intensity UndefinedPixelIntensityMethod PixelIntensityMethod
duration 0 unsigned int
the embedded blob information did indeed have an an undefined stream type:
Code: Select all
- blob 0x00972510 {length=0 extent=1074 quantum=65541 ...} _BlobInfo *
length 0 unsigned int
extent 1074 unsigned int
quantum 65541 unsigned int
mapped MagickFalse MagickBooleanType
eof MagickFalse MagickBooleanType
offset 0 __int64
size 1074 unsigned __int64
exempt MagickFalse MagickBooleanType
synchronize MagickFalse MagickBooleanType
status MagickFalse MagickBooleanType
temporary MagickFalse MagickBooleanType
[b]type UndefinedStream StreamType[/b]
+ file_info {file=0x00000000 gzfile=0x00000000 bzfile=0x00000000 } FileInfo
+ properties {st_dev=0 st_ino=0 st_mode=0 ...} _stat64
stream 0x00000000 unsigned int (const _Image *, const void *, const unsigned int)*
+ data 0x00000000 <Bad Ptr> unsigned char *
debug MagickFalse MagickBooleanType
+ semaphore 0x00972600 {mutex={...} id=20036 reference_count=0 ...} SemaphoreInfo *
reference_count 1 long
signature 2880220587 unsigned int
What is ImageToFile supposed to do? The core API's documentation is rather simple and doesn't indicate there would be any issue with this not performing as expected.
I did find another post on this website forum system saying to not use ImageToFile, but rather use WriteImage(imgMagickInfo, imgMagickImage);
Well, that does work as expected.
So now my question remains: what is the difference between the two, and note that ImageToFile is rather misleading in that section of the docs.
http://www.imagemagick.org/api/blob.php#ImageToFile.
ImageToFile
ImageToFile() writes an image to a file. It returns MagickFalse if an error occurs otherwise MagickTrue.
http://www.imagemagick.org/api/constitu ... WriteImage
WriteImage
WriteImage() writes an image or an image sequence to a file or file handle. If writing to a file is on disk, the name is defined by the filename member of the image structure. WriteImage() returns MagickFalse is there is a memory shortage or if the image cannot be written. Check the exception member of image to determine the cause for any failure.
Both indicate they write the image to a file.
My logical issue with what ever ImageToFile does is that it does NOT behave like ImageToBlob, except rather than to a blog it outputs to a file. And that is really confusing (beyond not knowing what ImageToFile is supposed to be used for).
For example, the following succesfully converts my TIFF blob, that was brought in as a TIFF image, into a PNG blob:
But if you try to do the same with ImageToFIle, you get our old friend, the assert fail.strcpy(imgMagickImage->filename, "internal.png" );
strcpy(imgMagickImage->magick, "png" );
unsigned char* pngBlob = ImageToBlob( imgMagickInfo, imgMagickImage, &pngSize, imgMagickException); // create the PNG blob