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
#include "magick/studio.h"
00043
#include "magick/blob.h"
00044
#include "magick/blob_private.h"
00045
#include "magick/colorspace.h"
00046
#include "magick/constitute.h"
00047
#include "magick/error.h"
00048
#include "magick/error_private.h"
00049
#include "magick/geometry.h"
00050
#include "magick/image.h"
00051
#include "magick/image_private.h"
00052
#include "magick/list.h"
00053
#include "magick/magick.h"
00054
#include "magick/memory_.h"
00055
#include "magick/monitor.h"
00056
#include "magick/nt_feature.h"
00057
#include "magick/static.h"
00058
#include "magick/string_.h"
00059
#if defined(HasJBIG)
00060
#include "jbig.h"
00061
#endif
00062
00063
00064
00065
00066
#if defined(HasJBIG)
00067
static MagickBooleanType
00068 WriteJBIGImage(
const ImageInfo *,
Image *);
00069
#endif
00070
00071
#if defined(HasJBIG)
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
static Image *ReadJBIGImage(
const ImageInfo *image_info,
00101
ExceptionInfo *
exception)
00102 {
00103
#define MaxBufferSize 8192
00104
00105
Image
00106 *image;
00107
00108
IndexPacket
00109 index;
00110
00111
long
00112 length,
00113 y;
00114
00115
MagickBooleanType
00116 status;
00117
00118
register IndexPacket
00119 *indexes;
00120
00121
register long
00122 x;
00123
00124
register PixelPacket
00125 *q;
00126
00127
register unsigned char
00128 *p;
00129
00130
ssize_t
00131 count;
00132
00133
struct jbg_dec_state
00134 jbig_info;
00135
00136
unsigned char
00137 bit,
00138 *buffer,
00139 byte;
00140
00141
00142
00143
00144
assert(image_info != (
const ImageInfo *) NULL);
00145
assert(image_info->
signature == MagickSignature);
00146
if (image_info->
debug !=
MagickFalse)
00147 (
void)
LogMagickEvent(TraceEvent,
GetMagickModule(),image_info->
filename);
00148
assert(exception != (
ExceptionInfo *) NULL);
00149
assert(exception->
signature == MagickSignature);
00150 image=
AllocateImage(image_info);
00151 status=
OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
00152
if (status ==
MagickFalse)
00153 {
00154
DestroyImageList(image);
00155
return((
Image *) NULL);
00156 }
00157
00158
00159
00160 jbg_dec_init(&jbig_info);
00161 jbg_dec_maxsize(&jbig_info,(
unsigned long) image->
columns,
00162 (
unsigned long) image->
rows);
00163 image->
columns= jbg_dec_getwidth(&jbig_info);
00164 image->
rows= jbg_dec_getheight(&jbig_info);
00165 image->
depth=8;
00166 image->
storage_class=
PseudoClass;
00167 image->
colors=2;
00168
00169
00170
00171 buffer=(
unsigned char *)
AcquireMagickMemory(MaxBufferSize);
00172
if (buffer == (
unsigned char *) NULL)
00173
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
00174 status=JBG_EAGAIN;
00175
do
00176 {
00177 length=(
long)
ReadBlob(image,MaxBufferSize,buffer);
00178
if (length == 0)
00179
break;
00180 p=buffer;
00181 count=0;
00182
while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
00183 {
00184
unsigned int
00185 count;
00186
00187 status=jbg_dec_in(&jbig_info,p,length,&count);
00188 p+=count;
00189 length-=count;
00190 }
00191 }
while ((status == JBG_EAGAIN) || (status == JBG_EOK));
00192
00193
00194
00195 image->
columns=jbg_dec_getwidth(&jbig_info);
00196 image->
rows=jbg_dec_getheight(&jbig_info);
00197
if (
AllocateImageColormap(image,2) ==
MagickFalse)
00198 {
00199 buffer=(
unsigned char *)
RelinquishMagickMemory(buffer);
00200
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
00201 }
00202 image->
colormap[0].
red=0;
00203 image->
colormap[0].
green=0;
00204 image->
colormap[0].
blue=0;
00205 image->
colormap[1].
red=
MaxRGB;
00206 image->
colormap[1].
green=
MaxRGB;
00207 image->
colormap[1].
blue=
MaxRGB;
00208 image->
x_resolution=300;
00209 image->
y_resolution=300;
00210
if (image_info->
ping !=
MagickFalse)
00211 {
00212
CloseBlob(image);
00213
return(
GetFirstImageInList(image));
00214 }
00215
00216
00217
00218 p=jbg_dec_getimage(&jbig_info,0);
00219
for (y=0; y < (
long) image->
rows; y++)
00220 {
00221 q=
SetImagePixels(image,0,y,image->
columns,1);
00222
if (q == (
PixelPacket *) NULL)
00223
break;
00224 indexes=
GetIndexes(image);
00225 bit=0;
00226 byte=0;
00227
for (x=0; x < (
long) image->
columns; x++)
00228 {
00229
if (bit == 0)
00230 byte=(*p++);
00231 index=(byte & 0x80) ? 0 : 1;
00232 bit++;
00233 byte<<=1;
00234
if (bit == 8)
00235 bit=0;
00236 indexes[x]=index;
00237 *q++=image->
colormap[index];
00238 }
00239
if (
SyncImagePixels(image) ==
MagickFalse)
00240
break;
00241
if ((image->
progress_monitor != (
MagickProgressMonitor) NULL) &&
00242 (
QuantumTick(y,image->
rows) !=
MagickFalse))
00243 {
00244 status=image->
progress_monitor(LoadImageTag,y,image->
rows,
00245 image->
client_data);
00246
if (status ==
MagickFalse)
00247
break;
00248 }
00249 }
00250
00251
00252
00253 jbg_dec_free(&jbig_info);
00254 buffer=(
unsigned char *)
RelinquishMagickMemory(buffer);
00255
CloseBlob(image);
00256
return(
GetFirstImageInList(image));
00257 }
00258
#endif
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 ModuleExport void RegisterJBIGImage(
void)
00284 {
00285
#define JBIGDescription "Joint Bi-level Image experts Group interchange format"
00286
00287
char
00288 version[
MaxTextExtent];
00289
00290
MagickInfo
00291 *entry;
00292
00293 *version=
'\0';
00294
#if defined(JBG_VERSION)
00295
(
void)
CopyMagickString(version,JBG_VERSION,
MaxTextExtent);
00296
#endif
00297
entry=
SetMagickInfo(
"BIE");
00298
#if defined(HasJBIG)
00299
entry->
decoder=(
DecoderHandler *) ReadJBIGImage;
00300 entry->
encoder=(
EncoderHandler *) WriteJBIGImage;
00301
#endif
00302
entry->
adjoin=
MagickFalse;
00303 entry->
description=
AcquireString(
JBIGDescription);
00304
if (*version !=
'\0')
00305 entry->
version=
AcquireString(version);
00306 entry->
module=
AcquireString(
"JBIG");
00307 (
void)
RegisterMagickInfo(entry);
00308 entry=
SetMagickInfo(
"JBG");
00309
#if defined(HasJBIG)
00310
entry->
decoder=(
DecoderHandler *) ReadJBIGImage;
00311 entry->
encoder=(
EncoderHandler *) WriteJBIGImage;
00312
#endif
00313
entry->
description=
AcquireString(
JBIGDescription);
00314
if (*version !=
'\0')
00315 entry->
version=
AcquireString(version);
00316 entry->
module=
AcquireString(
"JBIG");
00317 (
void)
RegisterMagickInfo(entry);
00318 entry=
SetMagickInfo(
"JBIG");
00319
#if defined(HasJBIG)
00320
entry->
decoder=(
DecoderHandler *) ReadJBIGImage;
00321 entry->
encoder=(
EncoderHandler *) WriteJBIGImage;
00322
#endif
00323
entry->
description=
AcquireString(
JBIGDescription);
00324
if (*version !=
'\0')
00325 entry->
version=
AcquireString(version);
00326 entry->
module=
AcquireString(
"JBIG");
00327 (
void)
RegisterMagickInfo(entry);
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 ModuleExport void UnregisterJBIGImage(
void)
00350 {
00351 (
void)
UnregisterMagickInfo(
"BIE");
00352 (
void)
UnregisterMagickInfo(
"JBG");
00353 (
void)
UnregisterMagickInfo(
"JBIG");
00354 }
00355
00356
#if defined(HasJBIG)
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
static void JBIGEncode(
unsigned char *pixels,size_t length,
void *data)
00384 {
00385
Image
00386 *image;
00387
00388 image=(
Image *) data;
00389 (
void)
WriteBlob(image,length,pixels);
00390 }
00391
00392
static MagickBooleanType WriteJBIGImage(
const ImageInfo *image_info,
Image *image)
00393 {
00394
long
00395 y;
00396
00397
MagickBooleanType
00398 status;
00399
00400
MagickOffsetType
00401 scene;
00402
00403
register const PixelPacket
00404 *p;
00405
00406
register IndexPacket
00407 *indexes;
00408
00409
register long
00410 x;
00411
00412
register unsigned char
00413 *q;
00414
00415
struct jbg_enc_state
00416 jbig_info;
00417
00418
unsigned char
00419 bit,
00420 byte,
00421 *pixels,
00422 polarity;
00423
00424
unsigned long
00425 number_packets;
00426
00427
00428
00429
00430
assert(image_info != (
const ImageInfo *) NULL);
00431
assert(image_info->
signature == MagickSignature);
00432
assert(image != (
Image *) NULL);
00433
assert(image->
signature == MagickSignature);
00434
if (image->
debug !=
MagickFalse)
00435 (
void)
LogMagickEvent(TraceEvent,
GetMagickModule(),image->
filename);
00436 status=
OpenBlob(image_info,image,WriteBinaryBlobMode,&image->
exception);
00437
if (status ==
MagickFalse)
00438
return(status);
00439 scene=0;
00440
do
00441 {
00442
00443
00444
00445 (
void)
SetImageColorspace(image,RGBColorspace);
00446 number_packets=((image->
columns+7) >> 3)*image->
rows;
00447 pixels=(
unsigned char *)
AcquireMagickMemory(number_packets);
00448
if (pixels == (
unsigned char *) NULL)
00449
ThrowWriterException(ResourceLimitError,
"MemoryAllocationFailed");
00450
00451
00452
00453
SetImageType(image,BilevelType);
00454 polarity=
PixelIntensityToQuantum(&image->
colormap[0]) < (
MaxRGB/2);
00455
if (image->
colors == 2)
00456 polarity=
PixelIntensityToQuantum(&image->
colormap[0]) >
00457
PixelIntensityToQuantum(&image->
colormap[1]);
00458 q=pixels;
00459
for (y=0; y < (
long) image->
rows; y++)
00460 {
00461 p=
AcquireImagePixels(image,0,y,image->
columns,1,&image->
exception);
00462
if (p == (
const PixelPacket *) NULL)
00463
break;
00464 indexes=
GetIndexes(image);
00465 bit=0;
00466 byte=0;
00467
for (x=0; x < (
long) image->
columns; x++)
00468 {
00469 byte<<=1;
00470
if (indexes[x] == polarity)
00471 byte|=0x01;
00472 bit++;
00473
if (bit == 8)
00474 {
00475 *q++=byte;
00476 bit=0;
00477 byte=0;
00478 }
00479 }
00480
if (bit != 0)
00481 *q++=byte << (8-bit);
00482
if ((image->
progress_monitor != (
MagickProgressMonitor) NULL) &&
00483 (
QuantumTick(y,image->
rows) !=
MagickFalse))
00484 {
00485 status=image->
progress_monitor(SaveImageTag,y,image->
rows,
00486 image->
client_data);
00487
if (status ==
MagickFalse)
00488
break;
00489 }
00490 }
00491
00492
00493
00494 jbg_enc_init(&jbig_info,image->
columns,image->
rows,1,&pixels,
00495 (void (*)(
unsigned char *,size_t,
void *)) JBIGEncode,image);
00496
if (image_info->
scene != 0)
00497 jbg_enc_layers(&jbig_info,(
int) image_info->
scene);
00498
else
00499 {
00500
long
00501 sans_offset;
00502
00503
unsigned long
00504 x_resolution,
00505 y_resolution;
00506
00507 x_resolution=640;
00508 y_resolution=480;
00509 sans_offset=0;
00510
if (image_info->
density != (
char *) NULL)
00511 {
00512
GeometryInfo
00513 geometry_info;
00514
00515
MagickStatusType
00516 flags;
00517
00518 flags=
ParseGeometry(image_info->
density,&geometry_info);
00519 x_resolution=geometry_info.
rho;
00520 y_resolution=geometry_info.
sigma;
00521
if ((flags &
SigmaValue) == 0)
00522 y_resolution=x_resolution;
00523 }
00524
if (image->
units ==
PixelsPerCentimeterResolution)
00525 {
00526 x_resolution*=2.54;
00527 y_resolution*=2.54;
00528 }
00529 (
void) jbg_enc_lrlmax(&jbig_info,x_resolution,y_resolution);
00530 }
00531 (
void) jbg_enc_lrange(&jbig_info,-1,-1);
00532 jbg_enc_options(&jbig_info,JBG_ILEAVE | JBG_SMID,JBG_TPDON | JBG_TPBON |
00533 JBG_DPON,-1,-1,-1);
00534
00535
00536
00537 jbg_enc_out(&jbig_info);
00538 jbg_enc_free(&jbig_info);
00539 pixels=(
unsigned char *)
RelinquishMagickMemory(pixels);
00540
if (image->
next == (
Image *) NULL)
00541
break;
00542 image=
SyncNextImageInList(image);
00543
if (image->
progress_monitor != (
MagickProgressMonitor) NULL)
00544 {
00545 status=image->
progress_monitor(SaveImagesTag,scene,
00546
GetImageListLength(image),image->
client_data);
00547
if (status ==
MagickFalse)
00548
break;
00549 }
00550 scene++;
00551 }
while (image_info->
adjoin !=
MagickFalse);
00552
CloseBlob(image);
00553
return(
MagickTrue);
00554 }
00555
#endif