Coverage Report

Created: 2026-07-20 07:19

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