00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
#include <setjmp.h>
00044
#include "magick/studio.h"
00045
#include "magick/attribute.h"
00046
#include "magick/blob.h"
00047
#include "magick/blob_private.h"
00048
#include "magick/color_private.h"
00049
#include "magick/color_private.h"
00050
#include "magick/colorspace.h"
00051
#include "magick/constitute.h"
00052
#include "magick/error.h"
00053
#include "magick/error_private.h"
00054
#include "magick/geometry.h"
00055
#include "magick/image.h"
00056
#include "magick/image_private.h"
00057
#include "magick/list.h"
00058
#include "magick/log.h"
00059
#include "magick/magick.h"
00060
#include "magick/memory_.h"
00061
#include "magick/monitor.h"
00062
#include "magick/profile.h"
00063
#include "magick/static.h"
00064
#include "magick/string_.h"
00065
#include "magick/utility.h"
00066
00067
#if defined(HasJPEG)
00068
#define JPEG_INTERNAL_OPTIONS
00069
#if defined(__MINGW32__)
00070
# define XMD_H 1
00071
#endif
00072
#undef HAVE_STDLIB_H
00073
#include "jpeglib.h"
00074
#include "jerror.h"
00075
#endif
00076
00077
00078
00079
00080 #define ICC_MARKER (JPEG_APP0+2)
00081 #define ICC_PROFILE "ICC_PROFILE"
00082 #define IPTC_MARKER (JPEG_APP0+13)
00083 #define XML_MARKER (JPEG_APP0+1)
00084 #define MaxBufferExtent 8192
00085
00086
00087
00088
00089
#if defined(HasJPEG)
00090
00091
typedef struct _ErrorManager
00092 {
00093
Image
00094 *image;
00095
00096 jmp_buf
00097 error_recovery;
00098
00099
boolean
00100 verbose;
00101 } ErrorManager;
00102
00103
typedef struct _SourceManager
00104 {
00105
struct jpeg_source_mgr
00106 manager;
00107
00108
Image
00109 *image;
00110
00111
unsigned char
00112 *source_data;
00113
00114 size_t
00115 source_length;
00116
00117 JOCTET
00118 *buffer;
00119
00120
boolean
00121 start_of_blob;
00122 } SourceManager;
00123
#endif
00124
00125
00126
00127
00128
00129 typedef struct _AVIInfo
00130 {
00131
unsigned long
00132 delay,
00133
max_data_rate,
00134
pad_granularity,
00135
flags,
00136
total_frames,
00137
initial_frames,
00138
number_streams,
00139
buffer_size,
00140
width,
00141
height,
00142
time_scale,
00143
data_rate,
00144
start_time,
00145
data_length;
00146 }
AVIInfo;
00147
00148 typedef struct _BMPInfo
00149 {
00150
unsigned long
00151 size,
00152
width,
00153
height,
00154
planes,
00155
bits_per_pixel;
00156
00157
char
00158 compression[5];
00159
00160
unsigned long
00161 image_size,
00162
x_pixels,
00163
y_pixels,
00164
number_colors,
00165
important_colors;
00166 }
BMPInfo;
00167
00168 typedef struct _StreamInfo
00169 {
00170
char
00171 data_type[5],
00172
data_handler[5];
00173
00174
unsigned long
00175 flags,
00176
priority,
00177
initial_frames,
00178
time_scale,
00179
data_rate,
00180
start_time,
00181
data_length,
00182
buffer_size,
00183
quality,
00184
sample_size;
00185 }
StreamInfo;
00186
00187
00188
00189
00190
#if defined(HasJPEG)
00191
#ifndef NOJPEGDIB
00192
00193
00194
#define JPEG_DIB mmioFOURCC('J','P','E','G')
00195
#define MJPG_DIB mmioFOURCC('M','J','P','G')
00196
00197
00198
#define JPEG_Y 1
00199
#define JPEG_YCbCr 2
00200
#define JPEG_RGB 3
00201
00202
00203
00204
#if defined(MAGICK_FUTURE)
00205
typedef struct tagJPEGINFOHEADER {
00206
00207
00208 DWORD JPEGSize;
00209 DWORD JPEGProcess;
00210
00211
00212 DWORD JPEGColorSpaceID;
00213 DWORD JPEGBitsPerSample;
00214 DWORD JPEGHSubSampling;
00215 DWORD JPEGVSubSampling;
00216 } JPEGINFOHEADER;
00217
#endif
00218
00219
00220
00221
static const unsigned char MJPGDHTSeg[0x1A8] = {
00222
00223 0xFF,0xD8,0xFF,0xC4,0x01,0xA2,
00224 0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00225 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x01,0x00,0x03,0x01,0x01,0x01,0x01,
00226 0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
00227 0x08,0x09,0x0A,0x0B,0x10,0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,
00228 0x00,0x01,0x7D,0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,
00229 0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24,
00230 0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29,0x2A,0x34,
00231 0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
00232 0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
00233 0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
00234 0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
00235 0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
00236 0xDA,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
00237 0xF8,0xF9,0xFA,0x11,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,
00238 0x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
00239 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,0x15,0x62,
00240 0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,0x27,0x28,0x29,0x2A,
00241 0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
00242 0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
00243 0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
00244 0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,
00245 0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,
00246 0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
00247 0xF9,0xFA,0xFF,0xD9
00248 };
00249
00250
00251
00252
00253
#endif
00254
#endif
00255
00256
00257
00258
#if defined(HasJPEG)
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
static MagickBooleanType EmitMessage(j_common_ptr jpeg_info,
int level)
00289 {
00290
char
00291 message[JMSG_LENGTH_MAX];
00292
00293 ErrorManager
00294 *error_manager;
00295
00296
Image
00297 *image;
00298
00299 (jpeg_info->err->format_message)(jpeg_info,message);
00300 error_manager=(ErrorManager *) jpeg_info->client_data;
00301 image=error_manager->image;
00302
if (error_manager->verbose !=
MagickFalse)
00303 (
void) fprintf(stdout,
"%s\n",message);
00304
if (level < 0)
00305 {
00306
if ((jpeg_info->err->num_warnings == 0) ||
00307 (jpeg_info->err->trace_level >= 3))
00308
ThrowBinaryException(CorruptImageError,(
char *) message,
00309 image->
filename);
00310 jpeg_info->err->num_warnings++;
00311 }
00312
else
00313
if (jpeg_info->err->trace_level >= level)
00314
ThrowBinaryException(CoderError,(
char *) message,image->
filename);
00315
return(
MagickTrue);
00316 }
00317
00318
static boolean FillInputBuffer(j_decompress_ptr cinfo)
00319 {
00320 SourceManager
00321 *source;
00322
00323 source=(SourceManager *) cinfo->src;
00324
if (source->image)
00325 source->manager.bytes_in_buffer=(size_t)
ReadBlob(source->image,
00326
Min(source->source_length,MaxBufferExtent),source->buffer);
00327
else
00328 {
00329 source->manager.bytes_in_buffer=(size_t)
00330
Min(source->source_length,MaxBufferExtent);
00331 (
void)
CopyMagickMemory(source->buffer,source->source_data,
00332 source->manager.bytes_in_buffer);
00333 source->source_data += source->manager.bytes_in_buffer;
00334 }
00335 source->source_length-=source->manager.bytes_in_buffer;
00336
if (source->manager.bytes_in_buffer == 0)
00337 {
00338
if (source->start_of_blob != 0)
00339 ERREXIT(cinfo,JERR_INPUT_EMPTY);
00340 WARNMS(cinfo,JWRN_JPEG_EOF);
00341 source->buffer[0]=(JOCTET) 0xff;
00342 source->buffer[1]=(JOCTET) JPEG_EOI;
00343 source->manager.bytes_in_buffer=2;
00344 }
00345 source->manager.next_input_byte=source->buffer;
00346 source->start_of_blob=FALSE;
00347
return(TRUE);
00348 }
00349
00350
static int GetCharacter(j_decompress_ptr jpeg_info)
00351 {
00352
if (jpeg_info->src->bytes_in_buffer == 0)
00353 (
void) (*jpeg_info->src->fill_input_buffer)(jpeg_info);
00354 jpeg_info->src->bytes_in_buffer--;
00355
return((
int) GETJOCTET(*jpeg_info->src->next_input_byte++));
00356 }
00357
00358
static void InitializeSource(j_decompress_ptr cinfo)
00359 {
00360 SourceManager
00361 *source;
00362
00363 source=(SourceManager *) cinfo->src;
00364 source->start_of_blob=TRUE;
00365 }
00366
00367
static void JPEGErrorHandler(j_common_ptr jpeg_info)
00368 {
00369 ErrorManager
00370 *error_manager;
00371
00372 (
void) EmitMessage(jpeg_info,0);
00373 error_manager=(ErrorManager *) jpeg_info->client_data;
00374 longjmp(error_manager->error_recovery,1);
00375 }
00376
00377
static boolean ReadComment(j_decompress_ptr jpeg_info)
00378 {
00379
char
00380 *comment;
00381
00382 ErrorManager
00383 *error_manager;
00384
00385
Image
00386 *image;
00387
00388
register char
00389 *p;
00390
00391
register long
00392 i;
00393
00394 size_t
00395 length;
00396
00397
00398
00399
00400 error_manager=(ErrorManager *) jpeg_info->
client_data;
00401 image=error_manager->image;
00402 length=(size_t) ((
unsigned long) GetCharacter(jpeg_info) << 8);
00403 length+=GetCharacter(jpeg_info);
00404 length-=2;
00405
if (length <= 0)
00406
return(
MagickTrue);
00407 comment=(
char *)
AcquireMagickMemory(length+MaxTextExtent);
00408
if (comment == (
char *) NULL)
00409
ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
00410 image->
filename);
00411
00412
00413
00414 i=(
long) length-1;
00415
for (p=comment; i-- >= 0; p++)
00416 *p=(
char) GetCharacter(jpeg_info);
00417 *p=
'\0';
00418 (
void)
SetImageAttribute(image,
"Comment",comment);
00419 comment=(
char *)
RelinquishMagickMemory(comment);
00420
return(
MagickTrue);
00421 }
00422
00423
static boolean ReadICCProfile(j_decompress_ptr jpeg_info)
00424 {
00425
char
00426 magick[12];
00427
00428 ErrorManager
00429 *error_manager;
00430
00431
Image
00432 *image;
00433
00434
MagickBooleanType
00435 status;
00436
00437
register long
00438 i;
00439
00440
register unsigned char
00441 *p;
00442
00443 size_t
00444 length;
00445
00446
StringInfo
00447 *icc_profile,
00448 *profile;
00449
00450
00451
00452
00453 length=(size_t) ((
unsigned long) GetCharacter(jpeg_info) << 8);
00454 length+=(size_t) GetCharacter(jpeg_info);
00455 length-=2;
00456
if (length <= 14)
00457 {
00458
while (length-- >= 0)
00459 (
void) GetCharacter(jpeg_info);
00460
return(
MagickTrue);
00461 }
00462
for (i=0; i < 12; i++)
00463 magick[i]=(
char) GetCharacter(jpeg_info);
00464
if (
LocaleCompare(magick,ICC_PROFILE) != 0)
00465 {
00466
00467
00468
00469
for (i=0; i < (
long) (length-12); i++)
00470 (
void) GetCharacter(jpeg_info);
00471
return(
MagickTrue);
00472 }
00473 (
void) GetCharacter(jpeg_info);
00474 (
void) GetCharacter(jpeg_info);
00475 length-=14;
00476 error_manager=(ErrorManager *) jpeg_info->client_data;
00477 image=error_manager->image;
00478 profile=
AcquireStringInfo(length);
00479
if (profile == (
StringInfo *) NULL)
00480
ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
00481 image->
filename);
00482 p=profile->
datum;
00483
for (i=(
long) profile->
length-1; i >= 0; i--)
00484 *p++=(
unsigned char) GetCharacter(jpeg_info);
00485 icc_profile=
GetImageProfile(image,
"icc");
00486
if (icc_profile != (
StringInfo *) NULL)
00487
ConcatenateStringInfo(icc_profile,profile);
00488
else
00489 {
00490 status=
SetImageProfile(image,
"icc",profile);
00491
if (status ==
MagickFalse)
00492
ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
00493 image->
filename);
00494 }
00495
if (image->
debug !=
MagickFalse)
00496 (
void)
LogMagickEvent(CoderEvent,
GetMagickModule(),
00497
"Profile: ICC, %lu bytes",(
unsigned long) length);
00498
return(
MagickTrue);
00499 }
00500
00501
static boolean ReadIPTCProfile(j_decompress_ptr jpeg_info)
00502 {
00503
char
00504 magick[
MaxTextExtent];
00505
00506 ErrorManager
00507 *error_manager;
00508
00509
Image
00510 *image;
00511
00512
MagickBooleanType
00513 status;
00514
00515
register long
00516 i;
00517
00518
register unsigned char
00519 *p;
00520
00521 size_t
00522 length,
00523 tag_length;
00524
00525
StringInfo
00526 *iptc_profile,
00527 *profile;
00528
00529
#ifdef GET_ONLY_IPTC_DATA
00530
unsigned char
00531 tag[
MaxTextExtent];
00532
#endif
00533
00534
00535
00536
00537 length=(size_t) ((
unsigned long) GetCharacter(jpeg_info) << 8);
00538 length+=(size_t) GetCharacter(jpeg_info);
00539
if (length <= 2)
00540
return(
MagickTrue);
00541 length-=2;
00542 tag_length=0;
00543
#ifdef GET_ONLY_IPTC_DATA
00544
*tag=
'\0';
00545
#endif
00546
error_manager=(ErrorManager *) jpeg_info->client_data;
00547 image=error_manager->image;
00548 iptc_profile=
GetImageProfile(image,
"iptc");
00549
if (iptc_profile == (
StringInfo *) NULL)
00550 {
00551
#ifdef GET_ONLY_IPTC_DATA
00552
00553
00554
00555
for (*tag=
'\0'; length > 0; )
00556 {
00557 *tag=GetCharacter(jpeg_info);
00558 *(tag+1)=GetCharacter(jpeg_info);
00559 length-=2;
00560
if ((*tag == 0x1c) && (*(tag+1) == 0x02))
00561
break;
00562 }
00563 tag_length=2;
00564
#else
00565
00566
00567
00568
for (i=0; i < 10; i++)
00569 magick[i]=(
char) GetCharacter(jpeg_info);
00570 magick[10]=
'\0';
00571
if (length <= 10)
00572
return(
MagickTrue);
00573 length-=10;
00574
if (
LocaleCompare(magick,
"Photoshop ") != 0)
00575 {
00576
00577
00578
00579
for (i=0; i < (
long) length; i++)
00580 (
void) GetCharacter(jpeg_info);
00581
return(
MagickTrue);
00582 }
00583
00584
00585
00586
for (i=0; i < 4; i++)
00587 (
void) GetCharacter(jpeg_info);
00588
if (length <= 4)
00589
return(
MagickTrue);
00590 length-=4;
00591 tag_length=0;
00592
#endif
00593
}
00594
if (length == 0)
00595
return(
MagickTrue);
00596 profile=
AcquireStringInfo(length);
00597
if (profile == (
StringInfo *) NULL)
00598
ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
00599 image->
filename);
00600 p=profile->
datum;
00601
for (i=(
long) profile->
length-1; i >= 0; i--)
00602 *p++=(
unsigned char) GetCharacter(jpeg_info);
00603 iptc_profile=
GetImageProfile(image,
"iptc");
00604
if (iptc_profile != (
StringInfo *) NULL)
00605
ConcatenateStringInfo(iptc_profile,profile);
00606
else
00607 {
00608 status=
SetImageProfile(image,
"iptc",profile);
00609
if (status ==
MagickFalse)
00610
ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
00611 image->
filename);
00612 }
00613
if (image->
debug !=
MagickFalse)
00614 (
void)
LogMagickEvent(CoderEvent,
GetMagickModule(),
00615
"Profile: iptc, %lu bytes",(
unsigned long) length);
00616
return(
MagickTrue);
00617 }
00618
00619
static boolean ReadProfile(j_decompress_ptr jpeg_info)
00620 {
00621
char
00622
name[
MaxTextExtent];
00623
00624 ErrorManager
00625 *error_manager;
00626
00627
Image
00628 *image;
00629
00630
int
00631 marker;
00632
00633
MagickBooleanType
00634 status;
00635
00636
register long
00637 i;
00638
00639
register unsigned char
00640 *p;
00641
00642 size_t
00643 length;
00644
00645
StringInfo
00646 *profile;
00647
00648
00649
00650
00651 length=(size_t) ((
unsigned long) GetCharacter(jpeg_info) << 8);
00652 length+=(size_t) GetCharacter(jpeg_info);
00653
if (length <= 2)
00654
return(
MagickTrue);
00655 length-=2;
00656 marker=jpeg_info->unread_marker-JPEG_APP0;
00657 error_manager=(ErrorManager *) jpeg_info->client_data;
00658 image=error_manager->image;
00659 (
void)
FormatMagickString(name,MaxTextExtent,
"APP%d",marker);
00660 profile=
AcquireStringInfo(length);
00661
if (profile == (
StringInfo *) NULL)
00662
ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
00663 image->
filename);
00664 p=profile->
datum;
00665
for (i=(
long) profile->
length-1; i >= 0; i--)
00666 *p++=(
unsigned char) GetCharacter(jpeg_info);
00667
if (marker == 1)
00668 {
00669 p=profile->
datum;
00670
if ((length > 4) && (
LocaleNCompare((
char *) p,
"exif",4) == 0))
00671 (
void)
CopyMagickString(name,
"iptc",MaxTextExtent);
00672
if ((length > 5) && (
LocaleNCompare((
char *) p,
"http:",5) == 0))
00673 (
void)
CopyMagickString(name,
"xmp",MaxTextExtent);
00674 }
00675 status=
SetImageProfile(image,name,profile);
00676
if (status ==
MagickFalse)
00677
ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
00678 image->
filename);
00679
if (image->
debug !=
MagickFalse)
00680 (
void)
LogMagickEvent(CoderEvent,
GetMagickModule(),
00681
"Profile: %s, %lu bytes",name,(
unsigned long) length);
00682
return(
MagickTrue);
00683 }
00684
00685
static void SkipInputData(j_decompress_ptr cinfo,
long number_bytes)
00686 {
00687 SourceManager
00688 *source;
00689
00690
if (number_bytes <= 0)
00691
return;
00692 source=(SourceManager *) cinfo->src;
00693
while (number_bytes > (
long) source->manager.bytes_in_buffer)
00694 {
00695 number_bytes-=(
long) source->manager.bytes_in_buffer;
00696 (
void) FillInputBuffer(cinfo);
00697 }
00698 source->manager.next_input_byte+=(size_t) number_bytes;
00699 source->manager.bytes_in_buffer-=(size_t) number_bytes;
00700 }
00701
00702
static void TerminateSource(j_decompress_ptr cinfo)
00703 {
00704 cinfo=cinfo;
00705 }
00706
00707
static void JPEGSourceManagerMemory(j_decompress_ptr cinfo,
unsigned char *source_data,
unsigned long source_length)
00708 {
00709 SourceManager
00710 *source;
00711
00712 cinfo->src=(
struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
00713 ((j_common_ptr) cinfo,JPOOL_IMAGE,
sizeof(SourceManager));
00714 source=(SourceManager *) cinfo->src;
00715 source->buffer=(JOCTET *) (*cinfo->mem->alloc_small)
00716 ((j_common_ptr) cinfo,JPOOL_IMAGE,
MaxBufferExtent*
sizeof(JOCTET));
00717 source=(SourceManager *) cinfo->src;
00718 source->manager.init_source=InitializeSource;
00719 source->manager.fill_input_buffer=FillInputBuffer;
00720 source->manager.skip_input_data=SkipInputData;
00721 source->manager.resync_to_restart=jpeg_resync_to_restart;
00722 source->manager.term_source=TerminateSource;
00723 source->manager.bytes_in_buffer=0;
00724 source->manager.next_input_byte=NULL;
00725 source->image=0;
00726 source->source_data=source_data;
00727 source->source_length=source_length;
00728 }
00729
00730
static void JPEGSourceManagerBLOB(j_decompress_ptr cinfo,
Image *image,
unsigned long source_length)
00731 {
00732 SourceManager
00733 *source;
00734
00735 cinfo->src=(
struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
00736 ((j_common_ptr) cinfo,JPOOL_IMAGE,
sizeof(SourceManager));
00737 source=(SourceManager *) cinfo->src;
00738 source->buffer=(JOCTET *) (*cinfo->mem->alloc_small)
00739 ((j_common_ptr) cinfo,JPOOL_IMAGE,
MaxBufferExtent*
sizeof(JOCTET));
00740 source=(SourceManager *) cinfo->src;
00741 source->manager.init_source=InitializeSource;
00742 source->manager.fill_input_buffer=FillInputBuffer;
00743 source->manager.skip_input_data=SkipInputData;
00744 source->manager.resync_to_restart=jpeg_resync_to_restart;
00745 source->manager.term_source=TerminateSource;
00746 source->manager.bytes_in_buffer=0;
00747 source->manager.next_input_byte=NULL;
00748 source->image=image;
00749 source->source_data=0;
00750 source->source_length=source_length;
00751 }
00752
00753
00754
#endif
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 static MagickBooleanType DecodeImage(
Image *image,
00788
const MagickBooleanType compression,
unsigned char *pixels)
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
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
00856
00857 count=
ReadBlobByte(image);
00858
if (count == 0x01)
00859
return(
MagickTrue);
00860
switch (count)
00861 {
00862
case 0x00:
00863 {
00864
00865
00866
00867 x=0;
00868 y++;
00869 p=pixels+y*image->
columns;
00870
break;
00871 }
00872
case 0x02:
00873 {
00874
00875
00876
00877 x+=
ReadBlobByte(image);
00878 y+=
ReadBlobByte(image);
00879 p=pixels+y*image->
columns+x;
00880
break;
00881 }
00882
default:
00883 {
00884
00885
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
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);
00925 (
void)
ReadBlobByte(image);
00926
return(
MagickTrue);
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 static MagickBooleanType IsAVI(
const unsigned char *magick,
const size_t length)
00957 {
00958
if (length < 4)
00959
return(
MagickFalse);
00960
if (memcmp(magick,
"RIFF",4) == 0)
00961
return(
MagickTrue);
00962
return(
MagickFalse);
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 static Image *
ReadAVIImage(
const ImageInfo *image_info,
ExceptionInfo *
exception)
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
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
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
01151
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
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
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
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
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
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
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
01572
01573 chunk_size = ((SourceManager *) jpeg_info.src)->source_length;
01574
for ( ; chunk_size != 0; chunk_size--)
01575 (
void)
ReadBlobByte(image);
01576
01577
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
01594
01595
else
01596 {
01597
01598
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/1