Coverage Report

Created: 2025-10-12 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/imagemagick/coders/cmyk.c
Line
Count
Source
1
/*
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%                                                                             %
4
%                                                                             %
5
%                                                                             %
6
%                         CCCC  M   M  Y   Y  K   K                           %
7
%                        C      MM MM   Y Y   K  K                            %
8
%                        C      M M M    Y    KKK                             %
9
%                        C      M   M    Y    K  K                            %
10
%                         CCCC  M   M    Y    K   K                           %
11
%                                                                             %
12
%                                                                             %
13
%                     Read/Write RAW CMYK Image Format                        %
14
%                                                                             %
15
%                              Software Design                                %
16
%                                   Cristy                                    %
17
%                                 July 1992                                   %
18
%                                                                             %
19
%                                                                             %
20
%  Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization         %
21
%  dedicated to making software imaging solutions freely available.           %
22
%                                                                             %
23
%  You may not use this file except in compliance with the License.  You may  %
24
%  obtain a copy of the License at                                            %
25
%                                                                             %
26
%    https://imagemagick.org/script/license.php                               %
27
%                                                                             %
28
%  Unless required by applicable law or agreed to in writing, software        %
29
%  distributed under the License is distributed on an "AS IS" BASIS,          %
30
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31
%  See the License for the specific language governing permissions and        %
32
%  limitations under the License.                                             %
33
%                                                                             %
34
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35
%
36
%
37
*/
38

39
/*
40
  Include declarations.
41
*/
42
#include "MagickCore/studio.h"
43
#include "MagickCore/blob.h"
44
#include "MagickCore/blob-private.h"
45
#include "MagickCore/cache.h"
46
#include "MagickCore/channel.h"
47
#include "MagickCore/colorspace.h"
48
#include "MagickCore/constitute.h"
49
#include "MagickCore/exception.h"
50
#include "MagickCore/exception-private.h"
51
#include "MagickCore/image.h"
52
#include "MagickCore/image-private.h"
53
#include "MagickCore/list.h"
54
#include "MagickCore/magick.h"
55
#include "MagickCore/memory_.h"
56
#include "MagickCore/monitor.h"
57
#include "MagickCore/monitor-private.h"
58
#include "MagickCore/pixel-accessor.h"
59
#include "MagickCore/quantum-private.h"
60
#include "MagickCore/static.h"
61
#include "MagickCore/statistic.h"
62
#include "MagickCore/string_.h"
63
#include "MagickCore/module.h"
64
#include "MagickCore/utility.h"
65

66
/*
67
  Forward declarations.
68
*/
69
static MagickBooleanType
70
  WriteCMYKImage(const ImageInfo *,Image *,ExceptionInfo *);
71

72
/*
73
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74
%                                                                             %
75
%                                                                             %
76
%                                                                             %
77
%   R e a d C M Y K I m a g e                                                 %
78
%                                                                             %
79
%                                                                             %
80
%                                                                             %
81
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82
%
83
%  ReadCMYKImage() reads an image of raw CMYK or CMYKA samples and returns it.
84
%  It allocates the memory necessary for the new Image structure and returns a
85
%  pointer to the new image.
86
%
87
%  The format of the ReadCMYKImage method is:
88
%
89
%      Image *ReadCMYKImage(const ImageInfo *image_info,
90
%        ExceptionInfo *exception)
91
%
92
%  A description of each parameter follows:
93
%
94
%    o image_info: the image info.
95
%
96
%    o exception: return any errors or warnings in this structure.
97
%
98
*/
99
static Image *ReadCMYKImage(const ImageInfo *image_info,
100
  ExceptionInfo *exception)
101
302
{
102
302
  const void
103
302
    *stream;
104
105
302
  Image
106
302
    *canvas_image,
107
302
    *image;
108
109
302
  MagickBooleanType
110
302
    status = MagickTrue;
111
112
302
  MagickOffsetType
113
302
    scene;
114
115
302
  QuantumInfo
116
302
    *quantum_info;
117
118
302
  QuantumType
119
302
    quantum_type;
120
121
302
  ssize_t
122
302
    i;
123
124
302
  size_t
125
302
    length;
126
127
302
  ssize_t
128
302
    count,
129
302
    y;
130
131
302
  unsigned char
132
302
    *pixels;
133
134
  /*
135
    Open image file.
136
  */
137
302
  assert(image_info != (const ImageInfo *) NULL);
138
302
  assert(image_info->signature == MagickCoreSignature);
139
302
  assert(exception != (ExceptionInfo *) NULL);
140
302
  assert(exception->signature == MagickCoreSignature);
141
302
  if (IsEventLogging() != MagickFalse)
142
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
143
0
      image_info->filename);
144
302
  image=AcquireImage(image_info,exception);
145
302
  if ((image->columns == 0) || (image->rows == 0))
146
302
    ThrowReaderException(OptionError,"MustSpecifyImageSize");
147
0
  status=SetImageExtent(image,image->columns,image->rows,exception);
148
0
  if (status == MagickFalse)
149
0
    return(DestroyImageList(image));
150
0
  (void) SetImageColorspace(image,CMYKColorspace,exception);
151
0
  if (image_info->interlace != PartitionInterlace)
152
0
    {
153
0
      status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
154
0
      if (status == MagickFalse)
155
0
        {
156
0
          image=DestroyImageList(image);
157
0
          return((Image *) NULL);
158
0
        }
159
0
      if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
160
0
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
161
0
          image->filename);
162
0
    }
163
  /*
164
    Create virtual canvas to support cropping (i.e. image.cmyk[100x100+10+20]).
165
  */
166
0
  canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
167
0
    exception);
168
0
  if (canvas_image == (Image *) NULL)
169
0
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
170
0
  quantum_type=CMYKQuantum;
171
0
  if (LocaleCompare(image_info->magick,"CMYKA") == 0)
172
0
    {
173
0
      quantum_type=CMYKAQuantum;
174
0
      canvas_image->alpha_trait=BlendPixelTrait;
175
0
    }
176
0
  (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
177
0
    exception);
178
0
  quantum_info=AcquireQuantumInfo(image_info,canvas_image);
179
0
  if (quantum_info == (QuantumInfo *) NULL)
180
0
    {
181
0
      canvas_image=DestroyImage(canvas_image);
182
0
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
183
0
    }
184
0
  pixels=GetQuantumPixels(quantum_info);
185
0
  if (image_info->number_scenes != 0)
186
0
    while (image->scene < image_info->scene)
187
0
    {
188
      /*
189
        Skip to next image.
190
      */
191
0
      image->scene++;
192
0
      length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
193
0
      for (y=0; y < (ssize_t) image->rows; y++)
194
0
      {
195
0
        stream=ReadBlobStream(image,length,pixels,&count);
196
0
        if (count != (ssize_t) length)
197
0
          break;
198
0
      }
199
0
    }
200
0
  count=0;
201
0
  length=0;
202
0
  scene=0;
203
0
  status=MagickTrue;
204
0
  stream=NULL;
205
0
  do
206
0
  {
207
    /*
208
      Read pixels to virtual canvas image then push to image.
209
    */
210
0
    image->alpha_trait=canvas_image->alpha_trait;
211
0
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
212
0
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
213
0
        break;
214
0
    status=SetImageExtent(image,image->columns,image->rows,exception);
215
0
    if (status == MagickFalse)
216
0
      break;
217
0
    if (SetImageColorspace(image,CMYKColorspace,exception) == MagickFalse)
218
0
      break;
219
0
    switch (image_info->interlace)
220
0
    {
221
0
      case NoInterlace:
222
0
      default:
223
0
      {
224
        /*
225
          No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
226
        */
227
0
        if (scene == 0)
228
0
          {
229
0
            length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
230
0
            stream=ReadBlobStream(image,length,pixels,&count);
231
0
          }
232
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
233
0
        {
234
0
          const Quantum
235
0
            *magick_restrict p;
236
237
0
          Quantum
238
0
            *magick_restrict q;
239
240
0
          ssize_t
241
0
            x;
242
243
0
          if (count != (ssize_t) length)
244
0
            {
245
0
              status=MagickFalse;
246
0
              ThrowFileException(exception,CorruptImageError,
247
0
                "UnexpectedEndOfFile",image->filename);
248
0
              break;
249
0
            }
250
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
251
0
            exception);
252
0
          if (q == (Quantum *) NULL)
253
0
            break;
254
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
255
0
            quantum_info,quantum_type,(unsigned char *) stream,exception);
256
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
257
0
            break;
258
0
          if (((y-image->extract_info.y) >= 0) && 
259
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
260
0
            {
261
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
262
0
                canvas_image->columns,1,exception);
263
0
              q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
264
0
                image->columns,1,exception);
265
0
              if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
266
0
                break;
267
0
              for (x=0; x < (ssize_t) image->columns; x++)
268
0
              {
269
0
                SetPixelRed(image,GetPixelRed(canvas_image,p),q);
270
0
                SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
271
0
                SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
272
0
                SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
273
0
                SetPixelAlpha(image,OpaqueAlpha,q);
274
0
                if (image->alpha_trait != UndefinedPixelTrait)
275
0
                  SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
276
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
277
0
                q+=(ptrdiff_t) GetPixelChannels(image);
278
0
              }
279
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
280
0
                break;
281
0
            }
282
0
          if (image->previous == (Image *) NULL)
283
0
            {
284
0
              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
285
0
                image->rows);
286
0
              if (status == MagickFalse)
287
0
                break;
288
0
            }
289
0
          stream=ReadBlobStream(image,length,pixels,&count);
290
0
        }
291
0
        break;
292
0
      }
293
0
      case LineInterlace:
294
0
      {
295
0
        static QuantumType
296
0
          quantum_types[5] =
297
0
          {
298
0
            CyanQuantum,
299
0
            MagentaQuantum,
300
0
            YellowQuantum,
301
0
            BlackQuantum,
302
0
            OpacityQuantum
303
0
          };
304
305
        /*
306
          Line interlacing:  CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
307
        */
308
0
        if (scene == 0)
309
0
          {
310
0
            length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
311
0
            stream=ReadBlobStream(image,length,pixels,&count);
312
0
          }
313
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
314
0
        {
315
0
          for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 5 : 4); i++)
316
0
          {
317
0
            const Quantum
318
0
              *magick_restrict p;
319
320
0
            Quantum
321
0
              *magick_restrict q;
322
323
0
            ssize_t
324
0
              x;
325
326
0
            if (count != (ssize_t) length)
327
0
              {
328
0
                status=MagickFalse;
329
0
                ThrowFileException(exception,CorruptImageError,
330
0
                  "UnexpectedEndOfFile",image->filename);
331
0
                break;
332
0
              }
333
0
            quantum_type=quantum_types[i];
334
0
            q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
335
0
              exception);
336
0
            if (q == (Quantum *) NULL)
337
0
              break;
338
0
            length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
339
0
              quantum_info,quantum_type,(unsigned char *) stream,exception);
340
0
            if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
341
0
              break;
342
0
            if (((y-image->extract_info.y) >= 0) && 
343
0
                ((y-image->extract_info.y) < (ssize_t) image->rows))
344
0
              {
345
0
                p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
346
0
                  0,canvas_image->columns,1,exception);
347
0
                q=GetAuthenticPixels(image,0,y-image->extract_info.y,
348
0
                  image->columns,1,exception);
349
0
                if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
350
0
                  break;
351
0
                for (x=0; x < (ssize_t) image->columns; x++)
352
0
                {
353
0
                  switch (quantum_type)
354
0
                  {
355
0
                    case CyanQuantum:
356
0
                    {
357
0
                      SetPixelCyan(image,GetPixelCyan(canvas_image,p),q);
358
0
                      break;
359
0
                    }
360
0
                    case MagentaQuantum:
361
0
                    {
362
0
                      SetPixelMagenta(image,GetPixelMagenta(canvas_image,p),q);
363
0
                      break;
364
0
                    }
365
0
                    case YellowQuantum:
366
0
                    {
367
0
                      SetPixelYellow(image,GetPixelYellow(canvas_image,p),q);
368
0
                      break;
369
0
                    }
370
0
                    case BlackQuantum:
371
0
                    {
372
0
                      SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
373
0
                      break;
374
0
                    }
375
0
                    case OpacityQuantum:
376
0
                    {
377
0
                      SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
378
0
                      break;
379
0
                    }
380
0
                    default:
381
0
                      break;
382
0
                  }
383
0
                  p+=(ptrdiff_t) GetPixelChannels(canvas_image);
384
0
                  q+=(ptrdiff_t) GetPixelChannels(image);
385
0
                }
386
0
                if (SyncAuthenticPixels(image,exception) == MagickFalse)
387
0
                  break;
388
0
              }
389
0
            stream=ReadBlobStream(image,length,pixels,&count);
390
0
          }
391
0
          if (image->previous == (Image *) NULL)
392
0
            {
393
0
              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
394
0
                image->rows);
395
0
              if (status == MagickFalse)
396
0
                break;
397
0
            }
398
0
        }
399
0
        break;
400
0
      }
401
0
      case PlaneInterlace:
402
0
      {
403
        /*
404
          Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
405
        */
406
0
        if (scene == 0)
407
0
          {
408
0
            length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
409
0
            stream=ReadBlobStream(image,length,pixels,&count);
410
0
          }
411
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
412
0
        {
413
0
          const Quantum
414
0
            *magick_restrict p;
415
416
0
          Quantum
417
0
            *magick_restrict q;
418
419
0
          ssize_t
420
0
            x;
421
422
0
          if (count != (ssize_t) length)
423
0
            {
424
0
              status=MagickFalse;
425
0
              ThrowFileException(exception,CorruptImageError,
426
0
                "UnexpectedEndOfFile",image->filename);
427
0
              break;
428
0
            }
429
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
430
0
            exception);
431
0
          if (q == (Quantum *) NULL)
432
0
            break;
433
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
434
0
            quantum_info,CyanQuantum,(unsigned char *) stream,exception);
435
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
436
0
            break;
437
0
          if (((y-image->extract_info.y) >= 0) && 
438
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
439
0
            {
440
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
441
0
                canvas_image->columns,1,exception);
442
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
443
0
                image->columns,1,exception);
444
0
              if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
445
0
                break;
446
0
              for (x=0; x < (ssize_t) image->columns; x++)
447
0
              {
448
0
                SetPixelRed(image,GetPixelRed(canvas_image,p),q);
449
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
450
0
                q+=(ptrdiff_t) GetPixelChannels(image);
451
0
              }
452
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
453
0
                break;
454
0
            }
455
0
          stream=ReadBlobStream(image,length,pixels,&count);
456
0
        }
457
0
        if (image->previous == (Image *) NULL)
458
0
          {
459
0
            status=SetImageProgress(image,LoadImageTag,1,6);
460
0
            if (status == MagickFalse)
461
0
              break;
462
0
          }
463
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
464
0
        {
465
0
          const Quantum
466
0
            *magick_restrict p;
467
468
0
          Quantum
469
0
            *magick_restrict q;
470
471
0
          ssize_t
472
0
            x;
473
474
0
          if (count != (ssize_t) length)
475
0
            {
476
0
              status=MagickFalse;
477
0
              ThrowFileException(exception,CorruptImageError,
478
0
                "UnexpectedEndOfFile",image->filename);
479
0
              break;
480
0
            }
481
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
482
0
            exception);
483
0
          if (q == (Quantum *) NULL)
484
0
            break;
485
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
486
0
            quantum_info,MagentaQuantum,(unsigned char *) stream,exception);
487
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
488
0
            break;
489
0
          if (((y-image->extract_info.y) >= 0) && 
490
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
491
0
            {
492
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
493
0
                canvas_image->columns,1,exception);
494
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
495
0
                image->columns,1,exception);
496
0
              if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
497
0
                break;
498
0
              for (x=0; x < (ssize_t) image->columns; x++)
499
0
              {
500
0
                SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
501
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
502
0
                q+=(ptrdiff_t) GetPixelChannels(image);
503
0
              }
504
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
505
0
                break;
506
0
           }
507
0
          stream=ReadBlobStream(image,length,pixels,&count);
508
0
        }
509
0
        if (image->previous == (Image *) NULL)
510
0
          {
511
0
            status=SetImageProgress(image,LoadImageTag,2,6);
512
0
            if (status == MagickFalse)
513
0
              break;
514
0
          }
515
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
516
0
        {
517
0
          const Quantum
518
0
            *magick_restrict p;
519
520
0
          Quantum
521
0
            *magick_restrict q;
522
523
0
          ssize_t
524
0
            x;
525
526
0
          if (count != (ssize_t) length)
527
0
            {
528
0
              status=MagickFalse;
529
0
              ThrowFileException(exception,CorruptImageError,
530
0
                "UnexpectedEndOfFile",image->filename);
531
0
              break;
532
0
            }
533
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
534
0
            exception);
535
0
          if (q == (Quantum *) NULL)
536
0
            break;
537
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
538
0
            quantum_info,YellowQuantum,(unsigned char *) stream,exception);
539
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
540
0
            break;
541
0
          if (((y-image->extract_info.y) >= 0) && 
542
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
543
0
            {
544
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
545
0
                canvas_image->columns,1,exception);
546
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
547
0
                image->columns,1,exception);
548
0
              if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
549
0
                break;
550
0
              for (x=0; x < (ssize_t) image->columns; x++)
551
0
              {
552
0
                SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
553
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
554
0
                q+=(ptrdiff_t) GetPixelChannels(image);
555
0
              }
556
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
557
0
                break;
558
0
            }
559
0
          stream=ReadBlobStream(image,length,pixels,&count);
560
0
        }
561
0
        if (image->previous == (Image *) NULL)
562
0
          {
563
0
            status=SetImageProgress(image,LoadImageTag,3,6);
564
0
            if (status == MagickFalse)
565
0
              break;
566
0
          }
567
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
568
0
        {
569
0
          const Quantum
570
0
            *magick_restrict p;
571
572
0
          Quantum
573
0
            *magick_restrict q;
574
575
0
          ssize_t
576
0
            x;
577
578
0
          if (count != (ssize_t) length)
579
0
            {
580
0
              status=MagickFalse;
581
0
              ThrowFileException(exception,CorruptImageError,
582
0
                "UnexpectedEndOfFile",image->filename);
583
0
              break;
584
0
            }
585
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
586
0
            exception);
587
0
          if (q == (Quantum *) NULL)
588
0
            break;
589
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
590
0
            quantum_info,BlackQuantum,(unsigned char *) stream,exception);
591
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
592
0
            break;
593
0
          if (((y-image->extract_info.y) >= 0) && 
594
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
595
0
            {
596
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
597
0
                canvas_image->columns,1,exception);
598
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
599
0
                image->columns,1,exception);
600
0
              if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
601
0
                break;
602
0
              for (x=0; x < (ssize_t) image->columns; x++)
603
0
              {
604
0
                SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
605
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
606
0
                q+=(ptrdiff_t) GetPixelChannels(image);
607
0
              }
608
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
609
0
                break;
610
0
            }
611
0
          stream=ReadBlobStream(image,length,pixels,&count);
612
0
        }
613
0
        if (image->previous == (Image *) NULL)
614
0
          {
615
0
            status=SetImageProgress(image,LoadImageTag,4,6);
616
0
            if (status == MagickFalse)
617
0
              break;
618
0
          }
619
0
        if (image->alpha_trait != UndefinedPixelTrait)
620
0
          {
621
0
            for (y=0; y < (ssize_t) image->extract_info.height; y++)
622
0
            {
623
0
              const Quantum
624
0
                *magick_restrict p;
625
626
0
              Quantum
627
0
                *magick_restrict q;
628
629
0
              ssize_t
630
0
                x;
631
632
0
              if (count != (ssize_t) length)
633
0
                {
634
0
                  status=MagickFalse;
635
0
                  ThrowFileException(exception,CorruptImageError,
636
0
                    "UnexpectedEndOfFile",image->filename);
637
0
                  break;
638
0
                }
639
0
              q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
640
0
                exception);
641
0
              if (q == (Quantum *) NULL)
642
0
                break;
643
0
              length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
644
0
                quantum_info,AlphaQuantum,(unsigned char *) stream,exception);
645
0
              if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
646
0
                break;
647
0
              if (((y-image->extract_info.y) >= 0) && 
648
0
                  ((y-image->extract_info.y) < (ssize_t) image->rows))
649
0
                {
650
0
                  p=GetVirtualPixels(canvas_image,
651
0
                    canvas_image->extract_info.x,0,canvas_image->columns,1,
652
0
                    exception);
653
0
                  q=GetAuthenticPixels(image,0,y-image->extract_info.y,
654
0
                    image->columns,1,exception);
655
0
                  if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
656
0
                    break;
657
0
                  for (x=0; x < (ssize_t) image->columns; x++)
658
0
                  {
659
0
                    SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
660
0
                    p+=(ptrdiff_t) GetPixelChannels(canvas_image);
661
0
                    q+=(ptrdiff_t) GetPixelChannels(image);
662
0
                  }
663
0
                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
664
0
                    break;
665
0
                }
666
0
              stream=ReadBlobStream(image,length,pixels,&count);
667
0
            }
668
0
            if (image->previous == (Image *) NULL)
669
0
              {
670
0
                status=SetImageProgress(image,LoadImageTag,5,6);
671
0
                if (status == MagickFalse)
672
0
                  break;
673
0
              }
674
0
          }
675
0
        if (image->previous == (Image *) NULL)
676
0
          {
677
0
            status=SetImageProgress(image,LoadImageTag,6,6);
678
0
            if (status == MagickFalse)
679
0
              break;
680
0
          }
681
0
        break;
682
0
      }
683
0
      case PartitionInterlace:
684
0
      {
685
        /*
686
          Partition interlacing:  CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
687
        */
688
0
        AppendImageFormat("C",image->filename);
689
0
        status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
690
0
        if (status == MagickFalse)
691
0
          break;
692
0
        if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
693
0
          {
694
0
            status=MagickFalse;
695
0
            ThrowFileException(exception,CorruptImageError,
696
0
              "UnexpectedEndOfFile",image->filename);
697
0
            break;
698
0
          }
699
0
        length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
700
0
        for (i=0; i < (ssize_t) scene; i++)
701
0
        {
702
0
          for (y=0; y < (ssize_t) image->extract_info.height; y++)
703
0
          {
704
0
            stream=ReadBlobStream(image,length,pixels,&count);
705
0
            if (count != (ssize_t) length)
706
0
              break;
707
0
          }
708
0
          if (count != (ssize_t) length)
709
0
            break;
710
0
        }
711
0
        stream=ReadBlobStream(image,length,pixels,&count);
712
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
713
0
        {
714
0
          const Quantum
715
0
            *magick_restrict p;
716
717
0
          Quantum
718
0
            *magick_restrict q;
719
720
0
          ssize_t
721
0
            x;
722
723
0
          if (count != (ssize_t) length)
724
0
            {
725
0
              status=MagickFalse;
726
0
              ThrowFileException(exception,CorruptImageError,
727
0
                "UnexpectedEndOfFile",image->filename);
728
0
              break;
729
0
            }
730
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
731
0
            exception);
732
0
          if (q == (Quantum *) NULL)
733
0
            break;
734
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
735
0
            quantum_info,CyanQuantum,(unsigned char *) stream,exception);
736
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
737
0
            break;
738
0
          if (((y-image->extract_info.y) >= 0) && 
739
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
740
0
            {
741
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
742
0
                canvas_image->columns,1,exception);
743
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
744
0
                image->columns,1,exception);
745
0
              if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
746
0
                break;
747
0
              for (x=0; x < (ssize_t) image->columns; x++)
748
0
              {
749
0
                SetPixelRed(image,GetPixelRed(canvas_image,p),q);
750
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
751
0
                q+=(ptrdiff_t) GetPixelChannels(image);
752
0
              }
753
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
754
0
                break;
755
0
            }
756
0
          stream=ReadBlobStream(image,length,pixels,&count);
757
0
        }
758
0
        if (image->previous == (Image *) NULL)
759
0
          {
760
0
            status=SetImageProgress(image,LoadImageTag,1,5);
761
0
            if (status == MagickFalse)
762
0
              break;
763
0
          }
764
0
        if (CloseBlob(image) == MagickFalse)
765
0
          break;
766
0
        AppendImageFormat("M",image->filename);
767
0
        status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
768
0
        if (status == MagickFalse)
769
0
          break;
770
0
        length=GetQuantumExtent(canvas_image,quantum_info,MagentaQuantum);
771
0
        for (i=0; i < (ssize_t) scene; i++)
772
0
        {
773
0
          for (y=0; y < (ssize_t) image->extract_info.height; y++)
774
0
          {
775
0
            stream=ReadBlobStream(image,length,pixels,&count);
776
0
            if (count != (ssize_t) length)
777
0
              break;
778
0
          }
779
0
          if (count != (ssize_t) length)
780
0
            break;
781
0
        }
782
0
        stream=ReadBlobStream(image,length,pixels,&count);
783
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
784
0
        {
785
0
          const Quantum
786
0
            *magick_restrict p;
787
788
0
          Quantum
789
0
            *magick_restrict q;
790
791
0
          ssize_t
792
0
            x;
793
794
0
          if (count != (ssize_t) length)
795
0
            {
796
0
              status=MagickFalse;
797
0
              ThrowFileException(exception,CorruptImageError,
798
0
                "UnexpectedEndOfFile",image->filename);
799
0
              break;
800
0
            }
801
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
802
0
            exception);
803
0
          if (q == (Quantum *) NULL)
804
0
            break;
805
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
806
0
            quantum_info,MagentaQuantum,(unsigned char *) stream,exception);
807
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
808
0
            break;
809
0
          if (((y-image->extract_info.y) >= 0) && 
810
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
811
0
            {
812
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
813
0
                canvas_image->columns,1,exception);
814
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
815
0
                image->columns,1,exception);
816
0
              if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
817
0
                break;
818
0
              for (x=0; x < (ssize_t) image->columns; x++)
819
0
              {
820
0
                SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
821
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
822
0
                q+=(ptrdiff_t) GetPixelChannels(image);
823
0
              }
824
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
825
0
                break;
826
0
           }
827
0
          stream=ReadBlobStream(image,length,pixels,&count);
828
0
        }
829
0
        if (image->previous == (Image *) NULL)
830
0
          {
831
0
            status=SetImageProgress(image,LoadImageTag,2,5);
832
0
            if (status == MagickFalse)
833
0
              break;
834
0
          }
835
0
        if (CloseBlob(image) == MagickFalse)
836
0
          break;
837
0
        AppendImageFormat("Y",image->filename);
838
0
        status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
839
0
        if (status == MagickFalse)
840
0
          break;
841
0
        length=GetQuantumExtent(canvas_image,quantum_info,YellowQuantum);
842
0
        for (i=0; i < (ssize_t) scene; i++)
843
0
        {
844
0
          for (y=0; y < (ssize_t) image->extract_info.height; y++)
845
0
          {
846
0
            stream=ReadBlobStream(image,length,pixels,&count);
847
0
            if (count != (ssize_t) length)
848
0
              break;
849
0
          }
850
0
          if (count != (ssize_t) length)
851
0
            break;
852
0
        }
853
0
        stream=ReadBlobStream(image,length,pixels,&count);
854
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
855
0
        {
856
0
          const Quantum
857
0
            *magick_restrict p;
858
859
0
          Quantum
860
0
            *magick_restrict q;
861
862
0
          ssize_t
863
0
            x;
864
865
0
          if (count != (ssize_t) length)
866
0
            {
867
0
              status=MagickFalse;
868
0
              ThrowFileException(exception,CorruptImageError,
869
0
                "UnexpectedEndOfFile",image->filename);
870
0
              break;
871
0
            }
872
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
873
0
            exception);
874
0
          if (q == (Quantum *) NULL)
875
0
            break;
876
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
877
0
            quantum_info,YellowQuantum,(unsigned char *) stream,exception);
878
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
879
0
            break;
880
0
          if (((y-image->extract_info.y) >= 0) && 
881
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
882
0
            {
883
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
884
0
                canvas_image->columns,1,exception);
885
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
886
0
                image->columns,1,exception);
887
0
              if ((p == (const Quantum *) NULL) ||
888
0
                  (q == (Quantum *) NULL))
889
0
                break;
890
0
              for (x=0; x < (ssize_t) image->columns; x++)
891
0
              {
892
0
                SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
893
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
894
0
                q+=(ptrdiff_t) GetPixelChannels(image);
895
0
              }
896
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
897
0
                break;
898
0
           }
899
0
          stream=ReadBlobStream(image,length,pixels,&count);
900
0
        }
901
0
        if (image->previous == (Image *) NULL)
902
0
          {
903
0
            status=SetImageProgress(image,LoadImageTag,3,5);
904
0
            if (status == MagickFalse)
905
0
              break;
906
0
          }
907
0
        if (CloseBlob(image) == MagickFalse)
908
0
          break;
909
0
        AppendImageFormat("K",image->filename);
910
0
        status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
911
0
        if (status == MagickFalse)
912
0
          break;
913
0
        length=GetQuantumExtent(canvas_image,quantum_info,BlackQuantum);
914
0
        for (i=0; i < (ssize_t) scene; i++)
915
0
        {
916
0
          for (y=0; y < (ssize_t) image->extract_info.height; y++)
917
0
          {
918
0
            stream=ReadBlobStream(image,length,pixels,&count);
919
0
            if (count != (ssize_t) length)
920
0
              break;
921
0
          }
922
0
          if (count != (ssize_t) length)
923
0
            break;
924
0
        }
925
0
        stream=ReadBlobStream(image,length,pixels,&count);
926
0
        for (y=0; y < (ssize_t) image->extract_info.height; y++)
927
0
        {
928
0
          const Quantum
929
0
            *magick_restrict p;
930
931
0
          Quantum
932
0
            *magick_restrict q;
933
934
0
          ssize_t
935
0
            x;
936
937
0
          if (count != (ssize_t) length)
938
0
            {
939
0
              status=MagickFalse;
940
0
              ThrowFileException(exception,CorruptImageError,
941
0
                "UnexpectedEndOfFile",image->filename);
942
0
              break;
943
0
            }
944
0
          q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
945
0
            exception);
946
0
          if (q == (Quantum *) NULL)
947
0
            break;
948
0
          length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
949
0
            quantum_info,BlackQuantum,(unsigned char *) stream,exception);
950
0
          if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
951
0
            break;
952
0
          if (((y-image->extract_info.y) >= 0) && 
953
0
              ((y-image->extract_info.y) < (ssize_t) image->rows))
954
0
            {
955
0
              p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
956
0
                canvas_image->columns,1,exception);
957
0
              q=GetAuthenticPixels(image,0,y-image->extract_info.y,
958
0
                image->columns,1,exception);
959
0
              if ((p == (const Quantum *) NULL) ||
960
0
                  (q == (Quantum *) NULL))
961
0
                break;
962
0
              for (x=0; x < (ssize_t) image->columns; x++)
963
0
              {
964
0
                SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
965
0
                p+=(ptrdiff_t) GetPixelChannels(canvas_image);
966
0
                q+=(ptrdiff_t) GetPixelChannels(image);
967
0
              }
968
0
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
969
0
                break;
970
0
           }
971
0
          stream=ReadBlobStream(image,length,pixels,&count);
972
0
        }
973
0
        if (image->previous == (Image *) NULL)
974
0
          {
975
0
            status=SetImageProgress(image,LoadImageTag,3,5);
976
0
            if (status == MagickFalse)
977
0
              break;
978
0
          }
979
0
        if (image->alpha_trait != UndefinedPixelTrait)
980
0
          {
981
0
            if (CloseBlob(image) == MagickFalse)
982
0
              break;
983
0
            AppendImageFormat("A",image->filename);
984
0
            status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
985
0
            if (status == MagickFalse)
986
0
              break;
987
0
            length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
988
0
            for (i=0; i < (ssize_t) scene; i++)
989
0
            {
990
0
              for (y=0; y < (ssize_t) image->extract_info.height; y++)
991
0
              {
992
0
                stream=ReadBlobStream(image,length,pixels,&count);
993
0
                if (count != (ssize_t) length)
994
0
                  break;
995
0
              }
996
0
              if (count != (ssize_t) length)
997
0
                break;
998
0
            }
999
0
            stream=ReadBlobStream(image,length,pixels,&count);
1000
0
            for (y=0; y < (ssize_t) image->extract_info.height; y++)
1001
0
            {
1002
0
              const Quantum
1003
0
                *magick_restrict p;
1004
1005
0
              Quantum
1006
0
                *magick_restrict q;
1007
1008
0
              ssize_t
1009
0
                x;
1010
1011
0
              if (count != (ssize_t) length)
1012
0
                {
1013
0
                  status=MagickFalse;
1014
0
                  ThrowFileException(exception,CorruptImageError,
1015
0
                    "UnexpectedEndOfFile",image->filename);
1016
0
                  break;
1017
0
                }
1018
0
              q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
1019
0
                exception);
1020
0
              if (q == (Quantum *) NULL)
1021
0
                break;
1022
0
              length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
1023
0
                quantum_info,YellowQuantum,(unsigned char *) stream,exception);
1024
0
              if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
1025
0
                break;
1026
0
              if (((y-image->extract_info.y) >= 0) && 
1027
0
                  ((y-image->extract_info.y) < (ssize_t) image->rows))
1028
0
                {
1029
0
                  p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
1030
0
                    0,canvas_image->columns,1,exception);
1031
0
                  q=GetAuthenticPixels(image,0,y-image->extract_info.y,
1032
0
                    image->columns,1,exception);
1033
0
                  if ((p == (const Quantum *) NULL) ||
1034
0
                      (q == (Quantum *) NULL))
1035
0
                    break;
1036
0
                  for (x=0; x < (ssize_t) image->columns; x++)
1037
0
                  {
1038
0
                    SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
1039
0
                    p+=(ptrdiff_t) GetPixelChannels(canvas_image);
1040
0
                    q+=(ptrdiff_t) GetPixelChannels(image);
1041
0
                  }
1042
0
                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
1043
0
                    break;
1044
0
               }
1045
0
              stream=ReadBlobStream(image,length,pixels,&count);
1046
0
            }
1047
0
            if (image->previous == (Image *) NULL)
1048
0
              {
1049
0
                status=SetImageProgress(image,LoadImageTag,4,5);
1050
0
                if (status == MagickFalse)
1051
0
                  break;
1052
0
              }
1053
0
          }
1054
0
        if (image->previous == (Image *) NULL)
1055
0
          {
1056
0
            status=SetImageProgress(image,LoadImageTag,5,5);
1057
0
            if (status == MagickFalse)
1058
0
              break;
1059
0
          }
1060
0
        break;
1061
0
      }
1062
0
    }
1063
0
    if (status == MagickFalse)
1064
0
      break;
1065
0
    SetQuantumImageType(image,quantum_type);
1066
    /*
1067
      Proceed to next image.
1068
    */
1069
0
    if (image_info->number_scenes != 0)
1070
0
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1071
0
        break;
1072
0
    if (count == (ssize_t) length)
1073
0
      {
1074
        /*
1075
          Allocate next image structure.
1076
        */
1077
0
        AcquireNextImage(image_info,image,exception);
1078
0
        if (GetNextImageInList(image) == (Image *) NULL)
1079
0
          {
1080
0
            status=MagickFalse;
1081
0
            break;
1082
0
          }
1083
0
        image=SyncNextImageInList(image);
1084
0
        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1085
0
          GetBlobSize(image));
1086
0
        if (status == MagickFalse)
1087
0
          break;
1088
0
      }
1089
0
    scene++;
1090
0
  } while (count == (ssize_t) length);
1091
0
  quantum_info=DestroyQuantumInfo(quantum_info);
1092
0
  canvas_image=DestroyImage(canvas_image);
1093
0
  if (CloseBlob(image) == MagickFalse)
1094
0
    status=MagickFalse;
1095
0
  if (status == MagickFalse)
1096
0
    return(DestroyImageList(image));
1097
0
  return(GetFirstImageInList(image));
1098
0
}
1099

1100
/*
1101
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102
%                                                                             %
1103
%                                                                             %
1104
%                                                                             %
1105
%   R e g i s t e r C M Y K I m a g e                                         %
1106
%                                                                             %
1107
%                                                                             %
1108
%                                                                             %
1109
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110
%
1111
%  RegisterCMYKImage() adds attributes for the CMYK image format to
1112
%  the list of supported formats.  The attributes include the image format
1113
%  tag, a method to read and/or write the format, whether the format
1114
%  supports the saving of more than one frame to the same file or blob,
1115
%  whether the format supports native in-memory I/O, and a brief
1116
%  description of the format.
1117
%
1118
%  The format of the RegisterCMYKImage method is:
1119
%
1120
%      size_t RegisterCMYKImage(void)
1121
%
1122
*/
1123
ModuleExport size_t RegisterCMYKImage(void)
1124
10
{
1125
10
  MagickInfo
1126
10
    *entry;
1127
1128
10
  entry=AcquireMagickInfo("CMYK","CMYK",
1129
10
    "Raw cyan, magenta, yellow, and black samples");
1130
10
  entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1131
10
  entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1132
10
  entry->flags|=CoderRawSupportFlag;
1133
10
  entry->flags|=CoderEndianSupportFlag;
1134
10
  (void) RegisterMagickInfo(entry);
1135
10
  entry=AcquireMagickInfo("CMYK","CMYKA",
1136
10
    "Raw cyan, magenta, yellow, black, and alpha samples");
1137
10
  entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1138
10
  entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1139
10
  entry->flags|=CoderRawSupportFlag;
1140
10
  entry->flags|=CoderEndianSupportFlag;
1141
10
  (void) RegisterMagickInfo(entry);
1142
10
  return(MagickImageCoderSignature);
1143
10
}
1144

1145
/*
1146
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147
%                                                                             %
1148
%                                                                             %
1149
%                                                                             %
1150
%   U n r e g i s t e r C M Y K I m a g e                                     %
1151
%                                                                             %
1152
%                                                                             %
1153
%                                                                             %
1154
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155
%
1156
%  UnregisterCMYKImage() removes format registrations made by the
1157
%  CMYK module from the list of supported formats.
1158
%
1159
%  The format of the UnregisterCMYKImage method is:
1160
%
1161
%      UnregisterCMYKImage(void)
1162
%
1163
*/
1164
ModuleExport void UnregisterCMYKImage(void)
1165
0
{
1166
0
  (void) UnregisterMagickInfo("CMYK");
1167
0
  (void) UnregisterMagickInfo("CMYKA");
1168
0
}
1169

1170
/*
1171
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1172
%                                                                             %
1173
%                                                                             %
1174
%                                                                             %
1175
%   W r i t e C M Y K I m a g e                                               %
1176
%                                                                             %
1177
%                                                                             %
1178
%                                                                             %
1179
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1180
%
1181
%  WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1182
%  black,rasterfile format.
1183
%
1184
%  The format of the WriteCMYKImage method is:
1185
%
1186
%      MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1187
%        Image *image,ExceptionInfo *exception)
1188
%
1189
%  A description of each parameter follows.
1190
%
1191
%    o image_info: the image info.
1192
%
1193
%    o image:  The image.
1194
%
1195
%    o exception: return any errors or warnings in this structure.
1196
%
1197
*/
1198
static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1199
  Image *image,ExceptionInfo *exception)
1200
0
{
1201
0
  MagickBooleanType
1202
0
    status = MagickTrue;
1203
1204
0
  MagickOffsetType
1205
0
    scene;
1206
1207
0
  QuantumInfo
1208
0
    *quantum_info;
1209
1210
0
  QuantumType
1211
0
    quantum_type;
1212
1213
0
  size_t
1214
0
    length,
1215
0
    number_scenes;
1216
1217
0
  ssize_t
1218
0
    count,
1219
0
    y;
1220
1221
0
  unsigned char
1222
0
    *pixels;
1223
1224
  /*
1225
    Allocate memory for pixels.
1226
  */
1227
0
  assert(image_info != (const ImageInfo *) NULL);
1228
0
  assert(image_info->signature == MagickCoreSignature);
1229
0
  assert(image != (Image *) NULL);
1230
0
  assert(image->signature == MagickCoreSignature);
1231
0
  if (IsEventLogging() != MagickFalse)
1232
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1233
0
  if (image_info->interlace != PartitionInterlace)
1234
0
    {
1235
      /*
1236
        Open output image file.
1237
      */
1238
0
      status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1239
0
      if (status == MagickFalse)
1240
0
        return(status);
1241
0
    }
1242
0
  scene=0;
1243
0
  number_scenes=GetImageListLength(image);
1244
0
  do
1245
0
  {
1246
    /*
1247
      Convert MIFF to CMYK raster pixels.
1248
    */
1249
0
    if (image->colorspace != CMYKColorspace)
1250
0
      (void) TransformImageColorspace(image,CMYKColorspace,exception);
1251
0
    quantum_type=CMYKQuantum;
1252
0
    if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1253
0
      {
1254
0
        quantum_type=CMYKAQuantum;
1255
0
        if ((image->alpha_trait & BlendPixelTrait) == 0)
1256
0
          (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1257
0
      }
1258
0
    quantum_info=AcquireQuantumInfo(image_info,image);
1259
0
    if (quantum_info == (QuantumInfo *) NULL)
1260
0
      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1261
0
    pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1262
0
    switch (image_info->interlace)
1263
0
    {
1264
0
      case NoInterlace:
1265
0
      default:
1266
0
      {
1267
        /*
1268
          No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
1269
        */
1270
0
        for (y=0; y < (ssize_t) image->rows; y++)
1271
0
        {
1272
0
          const Quantum
1273
0
            *magick_restrict p;
1274
1275
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1276
0
          if (p == (const Quantum *) NULL)
1277
0
            break;
1278
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1279
0
            quantum_type,pixels,exception);
1280
0
          count=WriteBlob(image,length,pixels);
1281
0
          if (count != (ssize_t) length)
1282
0
            break;
1283
0
          if (image->previous == (Image *) NULL)
1284
0
            {
1285
0
              status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1286
0
                image->rows);
1287
0
              if (status == MagickFalse)
1288
0
                break;
1289
0
            }
1290
0
        }
1291
0
        break;
1292
0
      }
1293
0
      case LineInterlace:
1294
0
      {
1295
        /*
1296
          Line interlacing:  CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
1297
        */
1298
0
        for (y=0; y < (ssize_t) image->rows; y++)
1299
0
        {
1300
0
          const Quantum
1301
0
            *magick_restrict p;
1302
1303
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1304
0
          if (p == (const Quantum *) NULL)
1305
0
            break;
1306
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1307
0
            CyanQuantum,pixels,exception);
1308
0
          count=WriteBlob(image,length,pixels);
1309
0
          if (count != (ssize_t) length)
1310
0
            break;
1311
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1312
0
            MagentaQuantum,pixels,exception);
1313
0
          count=WriteBlob(image,length,pixels);
1314
0
          if (count != (ssize_t) length)
1315
0
            break;
1316
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1317
0
            YellowQuantum,pixels,exception);
1318
0
          count=WriteBlob(image,length,pixels);
1319
0
          if (count != (ssize_t) length)
1320
0
            break;
1321
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1322
0
            BlackQuantum,pixels,exception);
1323
0
          count=WriteBlob(image,length,pixels);
1324
0
          if (count != (ssize_t) length)
1325
0
            break;
1326
0
          if (quantum_type == CMYKAQuantum)
1327
0
            {
1328
0
              length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1329
0
                AlphaQuantum,pixels,exception);
1330
0
              count=WriteBlob(image,length,pixels);
1331
0
              if (count != (ssize_t) length)
1332
0
                break;
1333
0
            }
1334
0
          if (image->previous == (Image *) NULL)
1335
0
            {
1336
0
              status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1337
0
                image->rows);
1338
0
              if (status == MagickFalse)
1339
0
                break;
1340
0
            }
1341
0
        }
1342
0
        break;
1343
0
      }
1344
0
      case PlaneInterlace:
1345
0
      {
1346
        /*
1347
          Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
1348
        */
1349
0
        for (y=0; y < (ssize_t) image->rows; y++)
1350
0
        {
1351
0
          const Quantum
1352
0
            *magick_restrict p;
1353
1354
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1355
0
          if (p == (const Quantum *) NULL)
1356
0
            break;
1357
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1358
0
            CyanQuantum,pixels,exception);
1359
0
          count=WriteBlob(image,length,pixels);
1360
0
          if (count != (ssize_t) length)
1361
0
            break;
1362
0
        }
1363
0
        if (image->previous == (Image *) NULL)
1364
0
          {
1365
0
            status=SetImageProgress(image,SaveImageTag,1,6);
1366
0
            if (status == MagickFalse)
1367
0
              break;
1368
0
          }
1369
0
        for (y=0; y < (ssize_t) image->rows; y++)
1370
0
        {
1371
0
          const Quantum
1372
0
            *magick_restrict p;
1373
1374
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1375
0
          if (p == (const Quantum *) NULL)
1376
0
            break;
1377
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1378
0
            MagentaQuantum,pixels,exception);
1379
0
          count=WriteBlob(image,length,pixels);
1380
0
          if (count != (ssize_t) length)
1381
0
            break;
1382
0
        }
1383
0
        if (image->previous == (Image *) NULL)
1384
0
          {
1385
0
            status=SetImageProgress(image,SaveImageTag,2,6);
1386
0
            if (status == MagickFalse)
1387
0
              break;
1388
0
          }
1389
0
        for (y=0; y < (ssize_t) image->rows; y++)
1390
0
        {
1391
0
          const Quantum
1392
0
            *magick_restrict p;
1393
1394
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1395
0
          if (p == (const Quantum *) NULL)
1396
0
            break;
1397
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1398
0
            YellowQuantum,pixels,exception);
1399
0
          count=WriteBlob(image,length,pixels);
1400
0
          if (count != (ssize_t) length)
1401
0
            break;
1402
0
        }
1403
0
        if (image->previous == (Image *) NULL)
1404
0
          {
1405
0
            status=SetImageProgress(image,SaveImageTag,3,6);
1406
0
            if (status == MagickFalse)
1407
0
              break;
1408
0
          }
1409
0
        for (y=0; y < (ssize_t) image->rows; y++)
1410
0
        {
1411
0
          const Quantum
1412
0
            *magick_restrict p;
1413
1414
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1415
0
          if (p == (const Quantum *) NULL)
1416
0
            break;
1417
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1418
0
            BlackQuantum,pixels,exception);
1419
0
          count=WriteBlob(image,length,pixels);
1420
0
          if (count != (ssize_t) length)
1421
0
            break;
1422
0
        }
1423
0
        if (image->previous == (Image *) NULL)
1424
0
          {
1425
0
            status=SetImageProgress(image,SaveImageTag,4,6);
1426
0
            if (status == MagickFalse)
1427
0
              break;
1428
0
          }
1429
0
        if (quantum_type == CMYKAQuantum)
1430
0
          {
1431
0
            for (y=0; y < (ssize_t) image->rows; y++)
1432
0
            {
1433
0
              const Quantum
1434
0
                *magick_restrict p;
1435
1436
0
              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1437
0
              if (p == (const Quantum *) NULL)
1438
0
                break;
1439
0
              length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1440
0
                AlphaQuantum,pixels,exception);
1441
0
              count=WriteBlob(image,length,pixels);
1442
0
              if (count != (ssize_t) length)
1443
0
              break;
1444
0
            }
1445
0
            if (image->previous == (Image *) NULL)
1446
0
              {
1447
0
                status=SetImageProgress(image,SaveImageTag,5,6);
1448
0
                if (status == MagickFalse)
1449
0
                  break;
1450
0
              }
1451
0
          }
1452
0
        if (image_info->interlace == PartitionInterlace)
1453
0
          (void) CopyMagickString(image->filename,image_info->filename,
1454
0
            MagickPathExtent);
1455
0
        if (image->previous == (Image *) NULL)
1456
0
          {
1457
0
            status=SetImageProgress(image,SaveImageTag,6,6);
1458
0
            if (status == MagickFalse)
1459
0
              break;
1460
0
          }
1461
0
        break;
1462
0
      }
1463
0
      case PartitionInterlace:
1464
0
      {
1465
        /*
1466
          Partition interlacing:  CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
1467
        */
1468
0
        AppendImageFormat("C",image->filename);
1469
0
        status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1470
0
          AppendBinaryBlobMode,exception);
1471
0
        if (status == MagickFalse)
1472
0
          return(status);
1473
0
        for (y=0; y < (ssize_t) image->rows; y++)
1474
0
        {
1475
0
          const Quantum
1476
0
            *magick_restrict p;
1477
1478
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1479
0
          if (p == (const Quantum *) NULL)
1480
0
            break;
1481
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1482
0
            CyanQuantum,pixels,exception);
1483
0
          count=WriteBlob(image,length,pixels);
1484
0
          if (count != (ssize_t) length)
1485
0
            break;
1486
0
        }
1487
0
        if (image->previous == (Image *) NULL)
1488
0
          {
1489
0
            status=SetImageProgress(image,SaveImageTag,1,6);
1490
0
            if (status == MagickFalse)
1491
0
              break;
1492
0
          }
1493
0
        if (CloseBlob(image) == MagickFalse)
1494
0
          break;
1495
0
        AppendImageFormat("M",image->filename);
1496
0
        status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1497
0
          AppendBinaryBlobMode,exception);
1498
0
        if (status == MagickFalse)
1499
0
          return(status);
1500
0
        for (y=0; y < (ssize_t) image->rows; y++)
1501
0
        {
1502
0
          const Quantum
1503
0
            *magick_restrict p;
1504
1505
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1506
0
          if (p == (const Quantum *) NULL)
1507
0
            break;
1508
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1509
0
            MagentaQuantum,pixels,exception);
1510
0
          count=WriteBlob(image,length,pixels);
1511
0
          if (count != (ssize_t) length)
1512
0
            break;
1513
0
        }
1514
0
        if (image->previous == (Image *) NULL)
1515
0
          {
1516
0
            status=SetImageProgress(image,SaveImageTag,2,6);
1517
0
            if (status == MagickFalse)
1518
0
              break;
1519
0
          }
1520
0
        if (CloseBlob(image) == MagickFalse)
1521
0
          break;
1522
0
        AppendImageFormat("Y",image->filename);
1523
0
        status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1524
0
          AppendBinaryBlobMode,exception);
1525
0
        if (status == MagickFalse)
1526
0
          return(status);
1527
0
        for (y=0; y < (ssize_t) image->rows; y++)
1528
0
        {
1529
0
          const Quantum
1530
0
            *magick_restrict p;
1531
1532
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1533
0
          if (p == (const Quantum *) NULL)
1534
0
            break;
1535
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1536
0
            YellowQuantum,pixels,exception);
1537
0
          count=WriteBlob(image,length,pixels);
1538
0
          if (count != (ssize_t) length)
1539
0
            break;
1540
0
        }
1541
0
        if (image->previous == (Image *) NULL)
1542
0
          {
1543
0
            status=SetImageProgress(image,SaveImageTag,3,6);
1544
0
            if (status == MagickFalse)
1545
0
              break;
1546
0
          }
1547
0
        if (CloseBlob(image) == MagickFalse)
1548
0
          break;
1549
0
        AppendImageFormat("K",image->filename);
1550
0
        status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1551
0
          AppendBinaryBlobMode,exception);
1552
0
        if (status == MagickFalse)
1553
0
          return(status);
1554
0
        for (y=0; y < (ssize_t) image->rows; y++)
1555
0
        {
1556
0
          const Quantum
1557
0
            *magick_restrict p;
1558
1559
0
          p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1560
0
          if (p == (const Quantum *) NULL)
1561
0
            break;
1562
0
          length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1563
0
            BlackQuantum,pixels,exception);
1564
0
          count=WriteBlob(image,length,pixels);
1565
0
          if (count != (ssize_t) length)
1566
0
            break;
1567
0
        }
1568
0
        if (image->previous == (Image *) NULL)
1569
0
          {
1570
0
            status=SetImageProgress(image,SaveImageTag,4,6);
1571
0
            if (status == MagickFalse)
1572
0
              break;
1573
0
          }
1574
0
        if (quantum_type == CMYKAQuantum)
1575
0
          {
1576
0
            if (CloseBlob(image) == MagickFalse)
1577
0
              break;
1578
0
            AppendImageFormat("A",image->filename);
1579
0
            status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1580
0
              AppendBinaryBlobMode,exception);
1581
0
            if (status == MagickFalse)
1582
0
              return(status);
1583
0
            for (y=0; y < (ssize_t) image->rows; y++)
1584
0
            {
1585
0
              const Quantum
1586
0
                *magick_restrict p;
1587
1588
0
              p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1589
0
              if (p == (const Quantum *) NULL)
1590
0
                break;
1591
0
              length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1592
0
                AlphaQuantum,pixels,exception);
1593
0
              count=WriteBlob(image,length,pixels);
1594
0
              if (count != (ssize_t) length)
1595
0
                break;
1596
0
            }
1597
0
            if (image->previous == (Image *) NULL)
1598
0
              {
1599
0
                status=SetImageProgress(image,SaveImageTag,5,6);
1600
0
                if (status == MagickFalse)
1601
0
                  break;
1602
0
              }
1603
0
          }
1604
0
        (void) CloseBlob(image);
1605
0
        (void) CopyMagickString(image->filename,image_info->filename,
1606
0
          MagickPathExtent);
1607
0
        if (image->previous == (Image *) NULL)
1608
0
          {
1609
0
            status=SetImageProgress(image,SaveImageTag,6,6);
1610
0
            if (status == MagickFalse)
1611
0
              break;
1612
0
          }
1613
0
        break;
1614
0
      }
1615
0
    }
1616
0
    quantum_info=DestroyQuantumInfo(quantum_info);
1617
0
    if (GetNextImageInList(image) == (Image *) NULL)
1618
0
      break;
1619
0
    image=SyncNextImageInList(image);
1620
0
    status=SetImageProgress(image,SaveImagesTag,scene++,number_scenes);
1621
0
    if (status == MagickFalse)
1622
0
      break;
1623
0
  } while (image_info->adjoin != MagickFalse);
1624
0
  if (CloseBlob(image) == MagickFalse)
1625
0
    status=MagickFalse;
1626
0
  return(status);
1627
0
}