Powered by Pair ImageMagick logo
Image Magick
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

ImageMagick-6.1.1/coders/avi.c File Reference

#include <setjmp.h>
#include "magick/studio.h"
#include "magick/attribute.h"
#include "magick/blob.h"
#include "magick/blob_private.h"
#include "magick/color_private.h"
#include "magick/colorspace.h"
#include "magick/constitute.h"
#include "magick/error.h"
#include "magick/error_private.h"
#include "magick/geometry.h"
#include "magick/image.h"
#include "magick/image_private.h"
#include "magick/list.h"
#include "magick/log.h"
#include "magick/magick.h"
#include "magick/memory_.h"
#include "magick/monitor.h"
#include "magick/profile.h"
#include "magick/static.h"
#include "magick/string_.h"
#include "magick/utility.h"

Include dependency graph for avi.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  _AVIInfo
struct  _BMPInfo
struct  _StreamInfo

Defines

#define ICC_MARKER   (JPEG_APP0+2)
#define ICC_PROFILE   "ICC_PROFILE"
#define IPTC_MARKER   (JPEG_APP0+13)
#define XML_MARKER   (JPEG_APP0+1)
#define MaxBufferExtent   8192
#define BI_RLE8   1

Typedefs

typedef _AVIInfo AVIInfo
typedef _BMPInfo BMPInfo
typedef _StreamInfo StreamInfo

Functions

MagickBooleanType DecodeImage (Image *image, const MagickBooleanType compression, unsigned char *pixels)
MagickBooleanType IsAVI (const unsigned char *magick, const size_t length)
ImageReadAVIImage (const ImageInfo *image_info, ExceptionInfo *exception)
ModuleExport void RegisterAVIImage (void)
ModuleExport void UnregisterAVIImage (void)


Define Documentation

#define BI_RLE8   1
 

Referenced by DecodeImage(), ReadBMPImage(), and WriteBMPImage().

#define ICC_MARKER   (JPEG_APP0+2)
 

Definition at line 80 of file avi.c.

Referenced by ReadAVIImage().

#define ICC_PROFILE   "ICC_PROFILE"
 

Definition at line 81 of file avi.c.

#define IPTC_MARKER   (JPEG_APP0+13)
 

Definition at line 82 of file avi.c.

Referenced by ReadAVIImage().

#define MaxBufferExtent   8192
 

Definition at line 84 of file avi.c.

#define XML_MARKER   (JPEG_APP0+1)
 

Definition at line 83 of file avi.c.


Typedef Documentation

typedef struct _AVIInfo AVIInfo
 

typedef struct _BMPInfo BMPInfo
 

typedef struct _StreamInfo StreamInfo
 

Referenced by AcquirePixelStream(), DestroyPixelStream(), GetIndexesFromStream(), GetPixelsFromStream(), SetPixelStream(), and SyncPixelStream().


Function Documentation

MagickBooleanType DecodeImage Image image,
const MagickBooleanType  compression,
unsigned char *  pixels
[static]
 

Definition at line 787 of file avi.c.

References assert, BI_RLE8, _Image::client_data, _Image::columns, _Image::debug, _Image::filename, GetMagickModule, LoadImageTag, LogMagickEvent(), MagickBooleanType, MagickFalse, MagickProgressMonitor, MagickSignature, MagickTrue, Min, _Image::progress_monitor, QuantumTick, ReadBlobByte(), ResetMagickMemory(), _Image::rows, _Image::signature, and TraceEvent.

00789 { 00790 #if !defined(__WINDOWS__) || defined(__MINGW32__) 00791 #define BI_RLE8 1 00792 #endif 00793 00794 int 00795 count; 00796 00797 long 00798 y; 00799 00800 MagickBooleanType 00801 status; 00802 00803 register long 00804 i, 00805 x; 00806 00807 register unsigned char 00808 *p, 00809 *q; 00810 00811 unsigned char 00812 byte; 00813 00814 assert(image != (Image *) NULL); 00815 assert(image->signature == MagickSignature); 00816 if (image->debug != MagickFalse) 00817 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00818 assert(pixels != (unsigned char *) NULL); 00819 (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows* 00820 sizeof(pixels)); 00821 byte=0; 00822 x=0; 00823 p=pixels; 00824 q=pixels+(size_t) image->columns*image->rows; 00825 for (y=0; y < (long) image->rows; ) 00826 { 00827 if ((p < pixels) || (p >= q)) 00828 break; 00829 count=ReadBlobByte(image); 00830 if (count == EOF) 00831 break; 00832 if (count != 0) 00833 { 00834 count=Min((unsigned long) count,q-p); 00835 /* 00836 Encoded mode. 00837 */ 00838 byte=(unsigned char) ReadBlobByte(image); 00839 if (compression == BI_RLE8) 00840 { 00841 for (i=0; i < count; i++) 00842 *p++=(unsigned char) byte; 00843 } 00844 else 00845 { 00846 for (i=0; i < count; i++) 00847 *p++=(unsigned char) 00848 ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f)); 00849 } 00850 x+=count; 00851 } 00852 else 00853 { 00854 /* 00855 Escape mode. 00856 */ 00857 count=ReadBlobByte(image); 00858 if (count == 0x01) 00859 return(MagickTrue); 00860 switch (count) 00861 { 00862 case 0x00: 00863 { 00864 /* 00865 End of line. 00866 */ 00867 x=0; 00868 y++; 00869 p=pixels+y*image->columns; 00870 break; 00871 } 00872 case 0x02: 00873 { 00874 /* 00875 Delta mode. 00876 */ 00877 x+=ReadBlobByte(image); 00878 y+=ReadBlobByte(image); 00879 p=pixels+y*image->columns+x; 00880 break; 00881 } 00882 default: 00883 { 00884 /* 00885 Absolute mode. 00886 */ 00887 count=Min((unsigned long) count,q-p); 00888 if (compression == BI_RLE8) 00889 for (i=0; i < count; i++) 00890 *p++=(unsigned char) ReadBlobByte(image); 00891 else 00892 for (i=0; i < count; i++) 00893 { 00894 if ((i & 0x01) == 0) 00895 byte=(unsigned char) ReadBlobByte(image); 00896 *p++=(unsigned char) 00897 ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f)); 00898 } 00899 x+=count; 00900 /* 00901 Read pad byte. 00902 */ 00903 if (compression == BI_RLE8) 00904 { 00905 if ((count & 0x01) != 0) 00906 (void) ReadBlobByte(image); 00907 } 00908 else 00909 if (((count & 0x03) == 1) || ((count & 0x03) == 2)) 00910 (void) ReadBlobByte(image); 00911 break; 00912 } 00913 } 00914 } 00915 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 00916 (QuantumTick(y,image->rows) != MagickFalse)) 00917 { 00918 status=image->progress_monitor(LoadImageTag,y,image->rows, 00919 image->client_data); 00920 if (status == MagickFalse) 00921 break; 00922 } 00923 } 00924 (void) ReadBlobByte(image); /* end of line */ 00925 (void) ReadBlobByte(image); 00926 return(MagickTrue); 00927 }

Here is the call graph for this function:

MagickBooleanType IsAVI const unsigned char *  magick,
const size_t  length
[static]
 

Definition at line 956 of file avi.c.

References MagickBooleanType, MagickFalse, and MagickTrue.

Referenced by RegisterAVIImage().

00957 { 00958 if (length < 4) 00959 return(MagickFalse); 00960 if (memcmp(magick,"RIFF",4) == 0) 00961 return(MagickTrue); 00962 return(MagickFalse); 00963 }

Image* ReadAVIImage const ImageInfo image_info,
ExceptionInfo exception
[static]
 

Definition at line 996 of file avi.c.

References AcquireMagickMemory(), AllocateImage(), AllocateImageColormap(), AllocateNextImage(), assert, _BMPInfo::bits_per_pixel, _PixelPacket::blue, _StreamInfo::buffer_size, _AVIInfo::buffer_size, _Image::client_data, CloseBlob(), CMYKColorspace, CoderEvent, _Image::colormap, _ImageInfo::colors, _Image::colorspace, _Image::columns, _Image::compression, _BMPInfo::compression, ConstrainColormapIndex(), CopyMagickMemory(), CorruptImageError, _StreamInfo::data_handler, _StreamInfo::data_length, _AVIInfo::data_length, _StreamInfo::data_rate, _AVIInfo::data_rate, _StreamInfo::data_type, _Image::debug, _ImageInfo::debug, DecodeImage(), _AVIInfo::delay, _Image::depth, DestroyImage(), DestroyImageList(), DirectClass, _Image::exception, _Image::filename, _ImageInfo::filename, _StreamInfo::flags, _AVIInfo::flags, FormatMagickString(), GeometryInfo, GetBlobSize(), GetFirstImageInList(), GetImageAttribute(), GetImagePixels(), GetIndexes(), GetMagickModule, _PixelPacket::green, _BMPInfo::height, _AVIInfo::height, ICC_MARKER, _BMPInfo::image_size, ImageAttribute, _BMPInfo::important_colors, IndexPacket, InheritException(), _StreamInfo::initial_frames, _AVIInfo::initial_frames, _Image::interlace, IPTC_MARKER, JPEGCompression, LoadImagesTag, LoadImageTag, LocaleCompare(), LogMagickEvent(), LosslessJPEGCompression, _Image::magick_columns, _Image::magick_rows, MagickBooleanType, MagickFalse, MagickProgressMonitor, MagickSignature, MagickTrue, _Image::matte, Max, _AVIInfo::max_data_rate, MaxRGB, MaxTextExtent, _Image::next, NoInterlace, _BMPInfo::number_colors, _ImageInfo::number_scenes, _AVIInfo::number_streams, _PixelPacket::opacity, OpenBlob(), OptionError, _AVIInfo::pad_granularity, ParseGeometry(), _ImageInfo::ping, PixelPacket, PixelsPerCentimeterResolution, PixelsPerInchResolution, PlaneInterlace, _BMPInfo::planes, _Image::previous, _StreamInfo::priority, _Image::progress_monitor, _StreamInfo::quality, Quantum, QuantumTick, ReadBinaryBlobMode, ReadBlob(), ReadBlobByte(), ReadBlobLSBLong(), ReadBlobLSBShort(), _PixelPacket::red, RelinquishMagickMemory(), ResetMagickMemory(), ResourceLimitError, _GeometryInfo::rho, _Image::rows, _StreamInfo::sample_size, ScaleCharToQuantum, ScaleColor5to8, ScaleColor6to8, ScaleShortToQuantum, _ImageInfo::scene, _Image::scene, SetImageAttribute(), SetImagePixels(), _GeometryInfo::sigma, _ExceptionInfo::signature, _ImageInfo::signature, _BMPInfo::size, ssize_t, _StreamInfo::start_time, _AVIInfo::start_time, _Image::storage_class, _ImageInfo::subrange, SyncImagePixels(), SyncNextImageInList(), TellBlob(), ThrowMagickException(), ThrowReaderException, _StreamInfo::time_scale, _AVIInfo::time_scale, _AVIInfo::total_frames, TraceEvent, _Image::units, _ImageAttribute::value, _ImageInfo::verbose, _BMPInfo::width, _AVIInfo::width, _BMPInfo::x_pixels, _Image::x_resolution, _BMPInfo::y_pixels, and _Image::y_resolution.

Referenced by RegisterAVIImage().

00997 { 00998 AVIInfo 00999 avi_info; 01000 01001 BMPInfo 01002 bmp_info; 01003 01004 char 01005 id[MaxTextExtent], 01006 message[MaxTextExtent]; 01007 01008 Image 01009 *image; 01010 01011 IndexPacket 01012 index; 01013 01014 long 01015 y; 01016 01017 MagickBooleanType 01018 status; 01019 01020 PixelPacket 01021 *colormap; 01022 01023 register IndexPacket 01024 *indexes; 01025 01026 register long 01027 x; 01028 01029 register PixelPacket 01030 *q; 01031 01032 register long 01033 i; 01034 01035 register unsigned char 01036 *p; 01037 01038 ssize_t 01039 count; 01040 01041 StreamInfo 01042 stream_info; 01043 01044 unsigned char 01045 *pixels; 01046 01047 unsigned long 01048 bit, 01049 bytes_per_line, 01050 chunk_size, 01051 number_colors; 01052 01053 #if defined(HasJPEG) 01054 const ImageAttribute 01055 *attribute; 01056 01057 ErrorManager 01058 error_manager; 01059 01060 GeometryInfo 01061 geometry_info; 01062 01063 JSAMPLE 01064 *jpeg_pixels; 01065 01066 JSAMPROW 01067 scanline[1]; 01068 01069 struct jpeg_decompress_struct 01070 jpeg_info; 01071 01072 struct jpeg_error_mgr 01073 jpeg_error; 01074 01075 unsigned long 01076 number_pixels, 01077 units; 01078 #endif 01079 01080 /* 01081 Open image file. 01082 */ 01083 assert(image_info != (const ImageInfo *) NULL); 01084 assert(image_info->signature == MagickSignature); 01085 if (image_info->debug != MagickFalse) 01086 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image_info->filename); 01087 assert(exception != (ExceptionInfo *) NULL); 01088 assert(exception->signature == MagickSignature); 01089 image=AllocateImage(image_info); 01090 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 01091 if (status == MagickFalse) 01092 { 01093 DestroyImageList(image); 01094 return((Image *) NULL); 01095 } 01096 (void) ResetMagickMemory(&avi_info,0,sizeof(AVIInfo)); 01097 (void) ResetMagickMemory(&bmp_info,0,sizeof(BMPInfo)); 01098 colormap=(PixelPacket *) NULL; 01099 number_colors=0; 01100 01101 #if defined(HasJPEG) 01102 /* 01103 Initialize JPEG image structure. 01104 */ 01105 jpeg_info.err=jpeg_std_error(&jpeg_error); 01106 jpeg_info.err->emit_message=(void (*)(j_common_ptr,int)) EmitMessage; 01107 jpeg_info.err->error_exit=(void (*)(j_common_ptr)) JPEGErrorHandler; 01108 jpeg_pixels=(JSAMPLE *) NULL; 01109 error_manager.image=image; 01110 error_manager.verbose=(int) image_info->verbose; 01111 if (setjmp(error_manager.error_recovery) != 0) 01112 { 01113 if (jpeg_pixels != (JSAMPLE *) NULL) 01114 jpeg_pixels=(unsigned char *) RelinquishMagickMemory(jpeg_pixels); 01115 jpeg_destroy_decompress(&jpeg_info); 01116 InheritException(exception,&image->exception); 01117 number_pixels=image->columns*image->rows; 01118 if (number_pixels != 0) 01119 return(GetFirstImageInList(image)); 01120 image=DestroyImage(image); 01121 return((Image *) NULL); 01122 } 01123 jpeg_info.client_data=(void *) &error_manager; 01124 jpeg_create_decompress(&jpeg_info); 01125 01126 JPEGSourceManagerMemory(&jpeg_info, (unsigned char *) &MJPGDHTSeg, 0x1A8); 01127 jpeg_read_header(&jpeg_info, FALSE); 01128 #endif 01129 01130 for ( ; ; ) 01131 { 01132 count=ReadBlob(image,4,(unsigned char *) id); 01133 if (count == 0) 01134 break; 01135 id[4]='\0'; 01136 chunk_size=ReadBlobLSBLong(image); 01137 if (chunk_size == 0) 01138 break; 01139 if ((chunk_size & 0x01) != 0) 01140 chunk_size++; 01141 if (image_info->verbose != MagickFalse) 01142 { 01143 (void) fprintf(stdout,"AVI cid %s\n",id); 01144 (void) fprintf(stdout," chunk size %lu\n",chunk_size); 01145 } 01146 if ((LocaleCompare(id,"00db") == 0) || (LocaleCompare(id,"00dc") == 0)) 01147 { 01148 01149 /* 01150 Read JPG compressed image, uses only YCbCr color space encoding 01151 and does not include the JPEG Huffman table, as it is pre-defined. 01152 */ 01153 if (LocaleCompare(bmp_info.compression,"MJPG") == 0) 01154 { 01155 #if defined(HasJPEG) 01156 JPEGSourceManagerBLOB(&jpeg_info,image,chunk_size); 01157 jpeg_set_marker_processor(&jpeg_info,JPEG_COM,ReadComment); 01158 jpeg_set_marker_processor(&jpeg_info,ICC_MARKER,ReadICCProfile); 01159 jpeg_set_marker_processor(&jpeg_info,IPTC_MARKER,ReadIPTCProfile); 01160 for (i=1; i < 16; i++) 01161 if ((i != 2) && (i != 13) && (i != 14)) 01162 jpeg_set_marker_processor(&jpeg_info,(int) i+JPEG_APP0,ReadProfile); 01163 i=jpeg_read_header(&jpeg_info,MagickTrue); 01164 if (jpeg_info.out_color_space == JCS_CMYK) 01165 image->colorspace=CMYKColorspace; 01166 /* 01167 Set image resolution. 01168 */ 01169 units=0; 01170 if ((jpeg_info.saw_JFIF_marker != 0) && (jpeg_info.X_density != 1) && 01171 (jpeg_info.Y_density != 1)) 01172 { 01173 image->x_resolution=(double) jpeg_info.X_density; 01174 image->y_resolution=(double) jpeg_info.Y_density; 01175 units=(unsigned long) jpeg_info.density_unit; 01176 } 01177 attribute=GetImageAttribute(image,"EXIF:XResolution"); 01178 if ((attribute != (const ImageAttribute *) NULL) && 01179 (attribute->value != (char *) NULL)) 01180 { 01181 (void) ParseGeometry(attribute->value,&geometry_info); 01182 if (geometry_info.sigma != 0) 01183 image->x_resolution=geometry_info.rho/geometry_info.sigma; 01184 (void) SetImageAttribute(image,"EXIF:XResolution",(char *) NULL); 01185 } 01186 attribute=GetImageAttribute(image,"EXIF:YResolution"); 01187 if ((attribute != (const ImageAttribute *) NULL) && 01188 (attribute->value != (char *) NULL)) 01189 { 01190 (void) ParseGeometry(attribute->value,&geometry_info); 01191 if (geometry_info.sigma != 0) 01192 image->y_resolution=geometry_info.rho/geometry_info.sigma; 01193 (void) SetImageAttribute(image,"EXIF:YResolution",(char *) NULL); 01194 } 01195 if (units == 1) 01196 image->units=PixelsPerInchResolution; 01197 if (units == 2) 01198 image->units=PixelsPerCentimeterResolution; 01199 number_pixels=image->columns*image->rows; 01200 if (number_pixels != 0) 01201 { 01202 double 01203 scale_factor; 01204 01205 /* 01206 Let the JPEG library subsample for us. 01207 */ 01208 jpeg_calc_output_dimensions(&jpeg_info); 01209 image->magick_columns=jpeg_info.output_width; 01210 image->magick_rows=jpeg_info.output_height; 01211 scale_factor=(double) jpeg_info.output_width/image->columns; 01212 if (scale_factor > ((double) jpeg_info.output_height/image->rows)) 01213 scale_factor=(double) jpeg_info.output_height/image->rows; 01214 jpeg_info.scale_denom=(unsigned int) scale_factor; 01215 jpeg_calc_output_dimensions(&jpeg_info); 01216 if (image->debug != MagickFalse) 01217 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Scale factor: %ld", 01218 (long) scale_factor); 01219 } 01220 if (image_info->subrange != 0) 01221 { 01222 jpeg_info.scale_denom=(unsigned int) image_info->subrange; 01223 jpeg_calc_output_dimensions(&jpeg_info); 01224 } 01225 #if (JPEG_LIB_VERSION >= 61) && defined(D_PROGRESSIVE_SUPPORTED) 01226 #ifdef D_LOSSLESS_SUPPORTED 01227 image->interlace= 01228 jpeg_info.process == JPROC_PROGRESSIVE ? PlaneInterlace : NoInterlace; 01229 image->compression=jpeg_info.process == JPROC_LOSSLESS ? 01230 LosslessJPEGCompression : JPEGCompression; 01231 if (jpeg_info.data_precision > 8) 01232 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, 01233 "12-bit JPEG not supported. Reducing pixel data to 8 bits", 01234 image->filename); 01235 #else 01236 image->interlace=jpeg_info.progressive_mode != 0 ? PlaneInterlace : 01237 NoInterlace; 01238 image->compression=JPEGCompression; 01239 #endif 01240 #else 01241 image->compression=JPEGCompression; 01242 image->interlace=PlaneInterlace; 01243 #endif 01244 if ((image_info->colors != 0) && (image_info->colors <= 256)) 01245 { 01246 /* 01247 Let the JPEG library quantize for us. 01248 */ 01249 jpeg_info.quantize_colors=MagickTrue; 01250 jpeg_info.desired_number_of_colors=(int) image_info->colors; 01251 if (AllocateImageColormap(image,image_info->colors) == MagickFalse) 01252 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01253 } 01254 (void) jpeg_start_decompress(&jpeg_info); 01255 image->columns=jpeg_info.output_width; 01256 image->rows=jpeg_info.output_height; 01257 image->depth=(unsigned long) jpeg_info.data_precision; 01258 if ((jpeg_info.output_components == 1) && 01259 (jpeg_info.quantize_colors == MagickFalse)) 01260 { 01261 if (AllocateImageColormap(image,1UL << image->depth) == MagickFalse) 01262 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01263 } 01264 if (image->debug != MagickFalse) 01265 { 01266 if (image->interlace == PlaneInterlace) 01267 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01268 "Interlace: progressive"); 01269 else 01270 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01271 "Interlace: nonprogressive"); 01272 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Data precision: %d", 01273 (int) jpeg_info.data_precision); 01274 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Geometry: %dx%d", 01275 (int) jpeg_info.output_width,(int) jpeg_info.output_height); 01276 #ifdef D_LOSSLESS_SUPPORTED 01277 if (image->compression==LosslessJPEGCompression) 01278 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01279 "Quality: 100 (lossless)"); 01280 else 01281 #endif 01282 { 01283 long 01284 hashval, 01285 sum; 01286 01287 /* 01288 Log the JPEG quality that was used for compression. 01289 */ 01290 sum=0; 01291 for (i=0; i < NUM_QUANT_TBLS; i++) 01292 { 01293 int 01294 j; 01295 01296 if (jpeg_info.quant_tbl_ptrs[i] != NULL) 01297 for (j=0; j < DCTSIZE2; j++) 01298 { 01299 UINT16 01300 *c; 01301 01302 c=jpeg_info.quant_tbl_ptrs[i]->quantval; 01303 sum+=c[j]; 01304 } 01305 } 01306 if ((jpeg_info.quant_tbl_ptrs[0] != NULL) && 01307 (jpeg_info.quant_tbl_ptrs[1] != NULL)) 01308 { 01309 int 01310 hash[]= 01311 { 01312 1020, 1015, 932, 848, 780, 735, 702, 679, 660, 645, 01313 632, 623, 613, 607, 600, 594, 589, 585, 581, 571, 01314 555, 542, 529, 514, 494, 474, 457, 439, 424, 410, 01315 397, 386, 373, 364, 351, 341, 334, 324, 317, 309, 01316 299, 294, 287, 279, 274, 267, 262, 257, 251, 247, 01317 243, 237, 232, 227, 222, 217, 213, 207, 202, 198, 01318 192, 188, 183, 177, 173, 168, 163, 157, 153, 148, 01319 143, 139, 132, 128, 125, 119, 115, 108, 104, 99, 01320 94, 90, 84, 79, 74, 70, 64, 59, 55, 49, 01321 45, 40, 34, 30, 25, 20, 15, 11, 6, 4, 01322 0 01323 }, 01324 sums[]= 01325 { 01326 32640,32635,32266,31495,30665,29804,29146,28599,28104,27670, 01327 27225,26725,26210,25716,25240,24789,24373,23946,23572,22846, 01328 21801,20842,19949,19121,18386,17651,16998,16349,15800,15247, 01329 14783,14321,13859,13535,13081,12702,12423,12056,11779,11513, 01330 11135,10955,10676,10392,10208, 9928, 9747, 9564, 9369, 9193, 01331 9017, 8822, 8639, 8458, 8270, 8084, 7896, 7710, 7527, 7347, 01332 7156, 6977, 6788, 6607, 6422, 6236, 6054, 5867, 5684, 5495, 01333 5305, 5128, 4945, 4751, 4638, 4442, 4248, 4065, 3888, 3698, 01334 3509, 3326, 3139, 2957, 2775, 2586, 2405, 2216, 2037, 1846, 01335 1666, 1483, 1297, 1109, 927, 735, 554, 375, 201, 128, 01336 0 01337 }; 01338 01339 hashval=(long) ((jpeg_info.quant_tbl_ptrs[0]->quantval[2]+ 01340 jpeg_info.quant_tbl_ptrs[0]->quantval[53]+ 01341 jpeg_info.quant_tbl_ptrs[1]->quantval[0]+ 01342 jpeg_info.quant_tbl_ptrs[1]->quantval[DCTSIZE2-1])); 01343 for (i=0; i < 100; i++) 01344 { 01345 if ((hashval >= hash[i]) || (sum >= sums[i])) 01346 { 01347 if ((hashval > hash[i]) || (sum > sums[i])) 01348 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01349 "Quality: %ld (approximate)",i+1); 01350 else 01351 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01352 "Quality: %ld",i+1); 01353 break; 01354 } 01355 } 01356 } 01357 else 01358 if (jpeg_info.quant_tbl_ptrs[0] != NULL) 01359 { 01360 int 01361 bwhash[]= 01362 { 01363 510, 505, 422, 380, 355, 338, 326, 318, 311, 305, 01364 300, 297, 293, 291, 288, 286, 284, 283, 281, 280, 01365 279, 278, 277, 273, 262, 251, 243, 233, 225, 218, 01366 211, 205, 198, 193, 186, 181, 177, 172, 168, 164, 01367 158, 156, 152, 148, 145, 142, 139, 136, 133, 131, 01368 129, 126, 123, 120, 118, 115, 113, 110, 107, 105, 01369 102, 100, 97, 94, 92, 89, 87, 83, 81, 79, 01370 76, 74, 70, 68, 66, 63, 61, 57, 55, 52, 01371 50, 48, 44, 42, 39, 37, 34, 31, 29, 26, 01372 24, 21, 18, 16, 13, 11, 8, 6, 3, 2, 01373 0 01374 }, 01375 bwsum[]= 01376 { 01377 16320,16315,15946,15277,14655,14073,13623,13230,12859,12560, 01378 12240,11861,11456,11081,10714,10360,10027, 9679, 9368, 9056, 01379 8680, 8331, 7995, 7668, 7376, 7084, 6823, 6562, 6345, 6125, 01380 5939, 5756, 5571, 5421, 5240, 5086, 4976, 4829, 4719, 4616, 01381 4463, 4393, 4280, 4166, 4092, 3980, 3909, 3835, 3755, 3688, 01382 3621, 3541, 3467, 3396, 3323, 3247, 3170, 3096, 3021, 2952, 01383 2874, 2804, 2727, 2657, 2583, 2509, 2437, 2362, 2290, 2211, 01384 2136, 2068, 1996, 1915, 1858, 1773, 1692, 1620, 1552, 1477, 01385 1398, 1326, 1251, 1179, 1109, 1031, 961, 884, 814, 736, 01386 667, 592, 518, 441, 369, 292, 221, 151, 86, 64, 01387 0 01388 }; 01389 01390 hashval=(long) ((jpeg_info.quant_tbl_ptrs[0]->quantval[2]+ 01391 jpeg_info.quant_tbl_ptrs[0]->quantval[53])); 01392 for (i=0; i < 100; i++) 01393 { 01394 if ((hashval >= bwhash[i]) || (sum >= bwsum[i])) 01395 { 01396 if ((hashval > bwhash[i]) || (sum > bwsum[i])) 01397 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01398 "Quality: %ld (approximate)",i+1); 01399 else 01400 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01401 "Quality: %ld",i+1); 01402 break; 01403 } 01404 } 01405 } 01406 } 01407 switch (jpeg_info.out_color_space) 01408 { 01409 case JCS_CMYK: 01410 { 01411 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01412 "Colorspace: CMYK"); 01413 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01414 "Sampling factors: (%d,%d),(%d,%d),(%d,%d),(%d,%d)", 01415 jpeg_info.comp_info[0].h_samp_factor, 01416 jpeg_info.comp_info[0].v_samp_factor, 01417 jpeg_info.comp_info[1].h_samp_factor, 01418 jpeg_info.comp_info[1].v_samp_factor, 01419 jpeg_info.comp_info[2].h_samp_factor, 01420 jpeg_info.comp_info[2].v_samp_factor, 01421 jpeg_info.comp_info[3].h_samp_factor, 01422 jpeg_info.comp_info[3].v_samp_factor); 01423 break; 01424 } 01425 case JCS_GRAYSCALE: 01426 { 01427 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01428 "Colorspace: GRAYSCALE"); 01429 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01430 "Sampling factors: (%d,%d)",jpeg_info.comp_info[0].h_samp_factor, 01431 jpeg_info.comp_info[0].v_samp_factor); 01432 break; 01433 } 01434 case JCS_RGB: 01435 { 01436 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Colorspace: RGB"); 01437 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01438 "Sampling factors: (%d,%d),(%d,%d),(%d,%d)", 01439 jpeg_info.comp_info[0].h_samp_factor, 01440 jpeg_info.comp_info[0].v_samp_factor, 01441 jpeg_info.comp_info[1].h_samp_factor, 01442 jpeg_info.comp_info[1].v_samp_factor, 01443 jpeg_info.comp_info[2].h_samp_factor, 01444 jpeg_info.comp_info[2].v_samp_factor); 01445 break; 01446 } 01447 default: 01448 { 01449 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Colorspace: %d", 01450 jpeg_info.out_color_space); 01451 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 01452 "Sampling factors: (%d,%d),(%d,%d),(%d,%d),(%d,%d)", 01453 jpeg_info.comp_info[0].h_samp_factor, 01454 jpeg_info.comp_info[0].v_samp_factor, 01455 jpeg_info.comp_info[1].h_samp_factor, 01456 jpeg_info.comp_info[1].v_samp_factor, 01457 jpeg_info.comp_info[2].h_samp_factor, 01458 jpeg_info.comp_info[2].v_samp_factor, 01459 jpeg_info.comp_info[3].h_samp_factor, 01460 jpeg_info.comp_info[3].v_samp_factor); 01461 break; 01462 } 01463 } 01464 } 01465 if (image_info->ping != MagickFalse) 01466 { 01467 jpeg_destroy_decompress(&jpeg_info); 01468 CloseBlob(image); 01469 return(GetFirstImageInList(image)); 01470 } 01471 jpeg_pixels=(JSAMPLE *) AcquireMagickMemory((size_t) 01472 jpeg_info.output_components*image->columns*sizeof(JSAMPLE)); 01473 if (jpeg_pixels == (JSAMPLE *) NULL) 01474 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01475 /* 01476 Convert JPEG pixels to pixel packets. 01477 */ 01478 scanline[0]=(JSAMPROW) jpeg_pixels; 01479 for (y=0; y < (long) image->rows; y++) 01480 { 01481 (void) jpeg_read_scanlines(&jpeg_info,scanline,1); 01482 p=jpeg_pixels; 01483 q=SetImagePixels(image,0,y,image->columns,1); 01484 if (q == (PixelPacket *) NULL) 01485 break; 01486 indexes=GetIndexes(image); 01487 if (jpeg_info.data_precision > 8) 01488 { 01489 if (jpeg_info.output_components == 1) 01490 for (x=0; x < (long) image->columns; x++) 01491 { 01492 index=ConstrainColormapIndex(image,16*(unsigned long) 01493 GETJSAMPLE(*p)); 01494 indexes[x]=(IndexPacket) index; 01495 *q++=image->colormap[index]; 01496 p++; 01497 } 01498 else 01499 for (x=0; x < (long) image->columns; x++) 01500 { 01501 q->red=ScaleShortToQuantum(16*GETJSAMPLE(*p++)); 01502 q->green=ScaleShortToQuantum(16*GETJSAMPLE(*p++)); 01503 q->blue=ScaleShortToQuantum(16*GETJSAMPLE(*p++)); 01504 if (image->colorspace == CMYKColorspace) 01505 indexes[x]=ScaleShortToQuantum(16*GETJSAMPLE(*p++)); 01506 q++; 01507 } 01508 } 01509 else 01510 if (jpeg_info.output_components == 1) 01511 for (x=0; x < (long) image->columns; x++) 01512 { 01513 index=ConstrainColormapIndex(image,(unsigned long) 01514 GETJSAMPLE(*p)); 01515 indexes[x]=(IndexPacket) index; 01516 *q++=image->colormap[index]; 01517 p++; 01518 } 01519 else 01520 for (x=0; x < (long) image->columns; x++) 01521 { 01522 q->red=ScaleCharToQuantum(GETJSAMPLE(*p++)); 01523 q->green=ScaleCharToQuantum(GETJSAMPLE(*p++)); 01524 q->blue=ScaleCharToQuantum(GETJSAMPLE(*p++)); 01525 if (image->colorspace == CMYKColorspace) 01526 indexes[x]=ScaleCharToQuantum(GETJSAMPLE(*p++)); 01527 q++; 01528 } 01529 if (SyncImagePixels(image) == MagickFalse) 01530 break; 01531 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 01532 (QuantumTick(y,image->rows) != MagickFalse)) 01533 { 01534 status=image->progress_monitor(LoadImageTag,y,image->rows, 01535 image->client_data); 01536 if (status == MagickFalse) 01537 break; 01538 } 01539 } 01540 if (jpeg_info.quantize_colors != MagickFalse) 01541 for (i=0; i < jpeg_info.actual_number_of_colors; i++) 01542 { 01543 image->colormap[i].red=ScaleCharToQuantum(jpeg_info.colormap[0][i]); 01544 image->colormap[i].green=ScaleCharToQuantum(jpeg_info.colormap[1][i]); 01545 image->colormap[i].blue=ScaleCharToQuantum(jpeg_info.colormap[2][i]); 01546 } 01547 if (image->colorspace == CMYKColorspace) 01548 { 01549 /* 01550 Correct CMYK levels. 01551 */ 01552 for (y=0; y < (long) image->rows; y++) 01553 { 01554 q=GetImagePixels(image,0,y,image->columns,1); 01555 if (q == (PixelPacket *) NULL) 01556 break; 01557 indexes=GetIndexes(image); 01558 for (x=0; x < (long) image->columns; x++) 01559 { 01560 q->red=(Quantum) (MaxRGB-q->red); 01561 q->green=(Quantum) (MaxRGB-q->green); 01562 q->blue=(Quantum) (MaxRGB-q->blue); 01563 indexes[x]=(IndexPacket) (MaxRGB-indexes[x]); 01564 q++; 01565 } 01566 if (SyncImagePixels(image) == MagickFalse) 01567 break; 01568 } 01569 } 01570 /* 01571 Consume Buffer. 01572 */ 01573 chunk_size = ((SourceManager *) jpeg_info.src)->source_length; 01574 for ( ; chunk_size != 0; chunk_size--) 01575 (void) ReadBlobByte(image); 01576 /* 01577 Free jpeg resources. 01578 */ 01579 (void) jpeg_finish_decompress(&jpeg_info); 01580 jpeg_pixels=(unsigned char *) RelinquishMagickMemory(jpeg_pixels); 01581 #else 01582 (void) FormatMagickString(message,MaxTextExtent, 01583 "AVI compression %s not yet supported",bmp_info.compression); 01584 (void) ThrowMagickException(exception,GetMagickModule(), 01585 CorruptImageError,message,image->filename); 01586 for ( ; chunk_size != 0; chunk_size--) 01587 (void) ReadBlobByte(image); 01588 continue; 01589 #endif 01590 } 01591 01592 /* 01593 Read BMP image 01594 */ 01595 else 01596 { 01597 /* 01598 Initialize image structure. 01599 */ 01600 image->columns=avi_info.width; 01601 image->rows=avi_info.height; 01602 image->depth=8; 01603 image->units=PixelsPerCentimeterResolution; 01604 image->x_resolution=(double) bmp_info.x_pixels/100.0; 01605 image->y_resolution=(double) bmp_info.y_pixels/100.0; 01606 status=AllocateImageColormap(image, 01607 number_colors != 0 ? number_colors : 256); 01608 if (status == MagickFalse) 01609 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01610 if (number_colors != 0) 01611 (void) CopyMagickMemory(image->colormap,colormap,(size_t) 01612 number_colors*sizeof(PixelPacket)); 01613 if ((image_info->ping != MagickFalse) && 01614 (image_info->number_scenes != 0)) 01615 if (image->scene >= (image_info->scene+image_info->number_scenes-1)) 01616 break; 01617 bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32); 01618 pixels=(unsigned char *) AcquireMagickMemory((size_t) 01619 Max(bytes_per_line,image->columns+256)*image->rows*sizeof(*pixels)); 01620 if (pixels == (unsigned char *) NULL) 01621 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01622 (void) ResetMagickMemory(pixels,0,(size_t) 01623 Max(bytes_per_line,image->columns+1)*image->rows); 01624 01625 if (LocaleCompare(id,"00db") == 0) 01626 (void) ReadBlob(image,(size_t) bytes_per_line*image->rows,pixels); 01627 else 01628 { 01629 status=DecodeImage(image,MagickTrue,pixels); 01630 if (status == MagickFalse) 01631 ThrowReaderException(CorruptImageError, 01632 "UnableToRunlengthDecodeImage"); 01633 } 01634 /* 01635 Convert BMP raster image to pixel packets. 01636 */ 01637 switch ((int) bmp_info.bits_per_pixel) 01638 { 01639 case 1: 01640 { 01641 /* 01642 Convert bitmap scanline. 01643 */ 01644 for (y=(long) image->rows-1; y >= 0; y--) 01645 { 01646 p=pixels+(image->rows-y-1)*bytes_per_line; 01647 q=SetImagePixels(image,0,y,image->columns,1); 01648 if (q == (PixelPacket *) NULL) 01649 break; 01650 indexes=GetIndexes(image); 01651 for (x=0; x < ((long) image->columns-7); x+=8) 01652 { 01653 for (bit=0; bit < 8; bit++) 01654 { 01655 index=(IndexPacket) 01656 (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00); 01657 indexes[x+bit]=index; 01658 *q++=image->colormap[index]; 01659 } 01660 p++; 01661 } 01662 if ((image->columns % 8) != 0) 01663 { 01664 for (bit=0; bit < (image->columns % 8); bit++) 01665 { 01666 index=(IndexPacket) 01667 (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00); 01668 indexes[x+bit]=index; 01669 *q++=image->colormap[index]; 01670 } 01671 p++; 01672 } 01673 if (SyncImagePixels(image) == MagickFalse) 01674 break; 01675 if (image->previous == (Image *) NULL) 01676 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 01677 (QuantumTick(image->rows-y-1,image->rows) != MagickFalse)) 01678 { 01679 status=image->progress_monitor(LoadImageTag,image->rows-y-1, 01680 image->rows,image->client_data); 01681 if (status == MagickFalse) 01682 break; 01683 } 01684 } 01685 break; 01686 } 01687 case 4: 01688 { 01689 /* 01690 Convert PseudoColor scanline. 01691 */ 01692 for (y=(long) image->rows-1; y >= 0; y--) 01693 { 01694 p=pixels+(image->rows-y-1)*bytes_per_line; 01695 q=SetImagePixels(image,0,y,image->columns,1); 01696 if (q == (PixelPacket *) NULL) 01697 break; 01698 indexes=GetIndexes(image); 01699 for (x=0; x < ((long) image->columns-1); x+=2) 01700 { 01701 index=ConstrainColormapIndex(image,((*p >> 4) & 0xf)); 01702 indexes[x]=index; 01703 *q++=image->colormap[index]; 01704 index=ConstrainColormapIndex(image,(*p & 0xf)); 01705 indexes[x+1]=index; 01706 *q++=image->colormap[index]; 01707 p++; 01708 } 01709 if ((image->columns % 2) != 0) 01710 { 01711 index=ConstrainColormapIndex(image,((*p >> 4) & 0xf)); 01712 indexes[x]=index; 01713 *q++=image->colormap[index]; 01714 p++; 01715 } 01716 if (SyncImagePixels(image) == MagickFalse) 01717 break; 01718 if (image->previous == (Image *) NULL) 01719 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 01720 (QuantumTick(image->rows-y-1,image->rows) != MagickFalse)) 01721 { 01722 status=image->progress_monitor(LoadImageTag,image->rows-y-1, 01723 image->rows,image->client_data); 01724 if (status == MagickFalse) 01725 break; 01726 } 01727 } 01728 break; 01729 } 01730 case 8: 01731 { 01732 /* 01733 Convert PseudoColor scanline. 01734 */ 01735 bytes_per_line=image->columns; 01736 for (y=(long) image->rows-1; y >= 0; y--) 01737 { 01738 p=pixels+(image->rows-y-1)*bytes_per_line; 01739 q=SetImagePixels(image,0,y,image->columns,1); 01740 if (q == (PixelPacket *) NULL) 01741 break; 01742 indexes=GetIndexes(image); 01743 for (x=0; x < (long) image->columns; x++) 01744 { 01745 index=ConstrainColormapIndex(image,*p); 01746 indexes[x]=index; 01747 *q=image->colormap[index]; 01748 p++; 01749 q++; 01750 } 01751 if (SyncImagePixels(image) == MagickFalse) 01752 break; 01753 if (image->previous == (Image *) NULL) 01754 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 01755 (QuantumTick(image->rows-y-1,image->rows) != MagickFalse)) 01756 { 01757 status=image->progress_monitor(LoadImageTag,image->rows-y-1, 01758 image->rows,image->client_data); 01759 if (status == MagickFalse) 01760 break; 01761 } 01762 } 01763 break; 01764 } 01765 case 16: 01766 { 01767 unsigned long 01768 word; 01769 01770 /* 01771 Convert PseudoColor scanline. 01772 */ 01773 bytes_per_line=image->columns << 1; 01774 image->storage_class=DirectClass; 01775 for (y=(long) image->rows-1; y >= 0; y--) 01776 { 01777 p=pixels+(image->rows-y-1)*bytes_per_line; 01778 q=SetImagePixels(image,0,y,image->columns,1); 01779 if (q == (PixelPacket *) NULL) 01780 break; 01781 for (x=0; x < (long) image->columns; x++) 01782 { 01783 word=(unsigned long) (*p++); 01784 word|=(*p++ << 8); 01785 q->red=ScaleCharToQuantum(ScaleColor5to8((word >> 11) & 0x1f)); 01786 q->green=ScaleCharToQuantum(ScaleColor6to8((word >> 5) & 0x3f)); 01787 q->blue=ScaleCharToQuantum(ScaleColor5to8(word & 0x1f)); 01788 q++; 01789 } 01790 if (SyncImagePixels(image) == MagickFalse) 01791 break; 01792 if (image->previous == (Image *) NULL) 01793 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 01794 (QuantumTick(image->rows-y-1,image->rows) != MagickFalse)) 01795 { 01796 status=image->progress_monitor(LoadImageTag,image->rows-y-1, 01797 image->rows,image->client_data); 01798 if (status == MagickFalse) 01799 break; 01800 } 01801 } 01802 break; 01803 } 01804 case 24: 01805 case 32: 01806 { 01807 /* 01808 Convert DirectColor scanline. 01809 */ 01810 image->storage_class=DirectClass; 01811 for (y=(long) image->rows-1; y >= 0; y--) 01812 { 01813 p=pixels+(image->rows-y-1)*bytes_per_line; 01814 q=SetImagePixels(image,0,y,image->columns,1); 01815 if (q == (PixelPacket *) NULL) 01816 break; 01817 for (x=0; x < (long) image->columns; x++) 01818 { 01819 q->blue=ScaleCharToQuantum(*p++); 01820 q->green=ScaleCharToQuantum(*p++); 01821 q->red=ScaleCharToQuantum(*p++); 01822 if (image->matte != MagickFalse) 01823 q->opacity=ScaleCharToQuantum(*p++); 01824 q++; 01825 } 01826 if (SyncImagePixels(image) == MagickFalse) 01827 break; 01828 if (image->previous == (Image *) NULL) 01829 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 01830 (QuantumTick(image->rows-y-1,image->rows) != MagickFalse)) 01831 { 01832 status=image->progress_monitor(LoadImageTag,image->rows-y-1, 01833 image->rows,image->client_data); 01834 if (status == MagickFalse) 01835 break; 01836 } 01837 } 01838 break; 01839 } 01840 default: 01841 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 01842 } 01843 pixels=(unsigned char *) RelinquishMagickMemory(pixels); 01844 } 01845 01846 /* 01847 Setup for next image 01848 */ 01849 01850 break; /* exit early after one image */ 01851 if ((unsigned long) image->scene < (avi_info.total_frames-1)) 01852 { 01853 /* 01854 Allocate next image structure. 01855 */ 01856 AllocateNextImage(image_info,image); 01857 if (image->next == (Image *) NULL) 01858 { 01859 DestroyImageList(image); 01860 return((Image *) NULL); 01861 } 01862 image=SyncNextImageInList(image); 01863 if (image->progress_monitor != (MagickProgressMonitor) NULL) 01864 { 01865 status=image->progress_monitor(LoadImagesTag,TellBlob(image), 01866 GetBlobSize(image),image->client_data); 01867 if (status == MagickFalse) 01868 break; 01869