blob: 0bff43650e854faa5868e6545e5c87bacb3afaf0 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% RRRR GGGG BBBB %
7% R R G B B %
8% RRRR G GG BBBB %
9% R R G G B B %
10% R R GGG BBBB %
11% %
12% %
13% Read/Write Raw RGB Image Format %
14% %
15% Software Design %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000017% July 1992 %
18% %
19% %
Cristy252dd2c2018-12-02 09:42:06 -050020% Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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% %
Cristy83d74de2018-10-13 10:17:25 -040026% https://imagemagick.org/script/license.php %
cristy3ed852e2009-09-05 21:47:34 +000027% %
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*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/cache.h"
cristy6a2180c2013-05-27 10:28:36 +000046#include "MagickCore/channel.h"
cristy4c08aed2011-07-01 19:47:50 +000047#include "MagickCore/colorspace.h"
cristy510d06a2011-07-06 23:43:54 +000048#include "MagickCore/colorspace-private.h"
cristy4c08aed2011-07-01 19:47:50 +000049#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"
cristy3ed852e2009-09-05 21:47:34 +000066
67/*
68 Forward declarations.
69*/
70static MagickBooleanType
cristy3a37efd2011-08-28 20:31:03 +000071 WriteRGBImage(const ImageInfo *,Image *,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +000072
73/*
74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75% %
76% %
77% %
78% R e a d R G B I m a g e %
79% %
80% %
81% %
82%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83%
cristy90dbac72010-08-22 15:08:40 +000084% ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
85% it. It allocates the memory necessary for the new Image structure and
86% returns a pointer to the new image.
cristy3ed852e2009-09-05 21:47:34 +000087%
88% The format of the ReadRGBImage method is:
89%
cristy90dbac72010-08-22 15:08:40 +000090% Image *ReadRGBImage(const ImageInfo *image_info,
91% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +000092%
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*/
cristyddacdd12012-05-07 23:08:14 +0000100static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000101{
cristyb3f97ae2015-05-18 12:29:32 +0000102 const unsigned char
cristybd797f12015-01-24 20:42:32 +0000103 *pixels;
104
cristy3ed852e2009-09-05 21:47:34 +0000105 Image
106 *canvas_image,
107 *image;
108
cristy3ed852e2009-09-05 21:47:34 +0000109 MagickBooleanType
110 status;
111
112 MagickOffsetType
113 scene;
114
115 QuantumInfo
116 *quantum_info;
117
118 QuantumType
119 quantum_type;
120
cristybb503372010-05-27 20:51:26 +0000121 register ssize_t
cristy90dbac72010-08-22 15:08:40 +0000122 i;
cristy3ed852e2009-09-05 21:47:34 +0000123
cristyc6da28e2011-04-28 01:41:35 +0000124 size_t
125 length;
126
cristy3ed852e2009-09-05 21:47:34 +0000127 ssize_t
cristya38675f2010-08-21 18:35:13 +0000128 count,
129 y;
cristy3ed852e2009-09-05 21:47:34 +0000130
cristy3ed852e2009-09-05 21:47:34 +0000131 /*
132 Open image file.
133 */
134 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000135 assert(image_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000136 if (image_info->debug != MagickFalse)
137 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
138 image_info->filename);
139 assert(exception != (ExceptionInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000140 assert(exception->signature == MagickCoreSignature);
cristy9950d572011-10-01 18:22:35 +0000141 image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +0000142 if ((image->columns == 0) || (image->rows == 0))
143 ThrowReaderException(OptionError,"MustSpecifyImageSize");
144 if (image_info->interlace != PartitionInterlace)
145 {
146 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
147 if (status == MagickFalse)
148 {
149 image=DestroyImageList(image);
150 return((Image *) NULL);
151 }
Cristyb2d24412018-03-09 19:41:19 -0500152 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
cristyd4297022010-09-16 22:59:09 +0000153 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
154 image->filename);
cristy3ed852e2009-09-05 21:47:34 +0000155 }
156 /*
157 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
158 */
159 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
160 exception);
root7a851d32017-09-28 17:39:04 +0000161 if(canvas_image == (Image *) NULL)
root67c24572017-09-28 16:57:54 +0000162 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristy387430f2012-02-07 13:09:46 +0000163 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
164 exception);
cristy5f766ef2014-12-14 21:12:47 +0000165 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
cristy3ed852e2009-09-05 21:47:34 +0000166 if (quantum_info == (QuantumInfo *) NULL)
Dirk Lemstradede8402018-03-24 17:51:58 +0100167 {
168 canvas_image=DestroyImage(canvas_image);
169 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
170 }
cristy3ed852e2009-09-05 21:47:34 +0000171 quantum_type=RGBQuantum;
cristy90dbac72010-08-22 15:08:40 +0000172 if (LocaleCompare(image_info->magick,"RGBA") == 0)
cristya38675f2010-08-21 18:35:13 +0000173 {
cristy90dbac72010-08-22 15:08:40 +0000174 quantum_type=RGBAQuantum;
cristy8a46d822012-08-28 23:32:39 +0000175 image->alpha_trait=BlendPixelTrait;
176 canvas_image->alpha_trait=BlendPixelTrait;
cristya38675f2010-08-21 18:35:13 +0000177 }
cristy90dbac72010-08-22 15:08:40 +0000178 if (LocaleCompare(image_info->magick,"RGBO") == 0)
179 {
180 quantum_type=RGBOQuantum;
dirk7000aae2015-02-24 11:56:06 +0000181 image->alpha_trait=BlendPixelTrait;
cristy8a46d822012-08-28 23:32:39 +0000182 canvas_image->alpha_trait=BlendPixelTrait;
cristy90dbac72010-08-22 15:08:40 +0000183 }
cristyb3f97ae2015-05-18 12:29:32 +0000184 pixels=(const unsigned char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +0000185 if (image_info->number_scenes != 0)
186 while (image->scene < image_info->scene)
187 {
188 /*
189 Skip to next image.
190 */
191 image->scene++;
192 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +0000193 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000194 {
cristyb3f97ae2015-05-18 12:29:32 +0000195 pixels=(const unsigned char *) ReadBlobStream(image,length,
196 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000197 if (count != (ssize_t) length)
198 break;
199 }
200 }
cristy3ed852e2009-09-05 21:47:34 +0000201 count=0;
202 length=0;
203 scene=0;
Dirk Lemstradede8402018-03-24 17:51:58 +0100204 status=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +0000205 do
206 {
207 /*
208 Read pixels to virtual canvas image then push to image.
209 */
210 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
211 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
212 break;
cristyacabb842014-12-14 23:36:33 +0000213 status=SetImageExtent(image,image->columns,image->rows,exception);
214 if (status == MagickFalse)
Dirk Lemstradede8402018-03-24 17:51:58 +0100215 break;
cristy3ed852e2009-09-05 21:47:34 +0000216 switch (image_info->interlace)
217 {
218 case NoInterlace:
219 default:
220 {
221 /*
222 No interlacing: RGBRGBRGBRGBRGBRGB...
223 */
224 if (scene == 0)
225 {
226 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
cristyb3f97ae2015-05-18 12:29:32 +0000227 pixels=(const unsigned char *) ReadBlobStream(image,length,
228 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000229 }
cristybb503372010-05-27 20:51:26 +0000230 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000231 {
cristy4c08aed2011-07-01 19:47:50 +0000232 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100233 *magick_restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000234
cristy4c08aed2011-07-01 19:47:50 +0000235 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100236 *magick_restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000237
cristy90dbac72010-08-22 15:08:40 +0000238 register ssize_t
239 x;
240
cristy21da32d2009-09-12 14:56:09 +0000241 if (count != (ssize_t) length)
242 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100243 status=MagickFalse;
cristy21da32d2009-09-12 14:56:09 +0000244 ThrowFileException(exception,CorruptImageError,
245 "UnexpectedEndOfFile",image->filename);
246 break;
247 }
cristy3ed852e2009-09-05 21:47:34 +0000248 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
249 exception);
cristyacd2ed22011-08-30 01:44:23 +0000250 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000251 break;
252 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
253 quantum_info,quantum_type,pixels,exception);
254 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
255 break;
Cristy747a7342019-06-03 21:01:22 -0400256 if (((y-image->extract_info.y) >= 0) &&
cristybb503372010-05-27 20:51:26 +0000257 ((y-image->extract_info.y) < (ssize_t) image->rows))
cristy3ed852e2009-09-05 21:47:34 +0000258 {
259 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
260 canvas_image->columns,1,exception);
261 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
262 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000263 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy3ed852e2009-09-05 21:47:34 +0000264 break;
cristybb503372010-05-27 20:51:26 +0000265 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000266 {
cristy4c08aed2011-07-01 19:47:50 +0000267 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
268 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
269 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
270 SetPixelAlpha(image,OpaqueAlpha,q);
cristy17f11b02014-12-20 19:37:04 +0000271 if (image->alpha_trait != UndefinedPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +0000272 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000273 p+=GetPixelChannels(canvas_image);
274 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000275 }
276 if (SyncAuthenticPixels(image,exception) == MagickFalse)
277 break;
278 }
279 if (image->previous == (Image *) NULL)
280 {
cristycee97112010-05-28 00:44:52 +0000281 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
282 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000283 if (status == MagickFalse)
284 break;
285 }
cristyb3f97ae2015-05-18 12:29:32 +0000286 pixels=(const unsigned char *) ReadBlobStream(image,length,
287 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000288 }
289 break;
290 }
291 case LineInterlace:
292 {
cristy90dbac72010-08-22 15:08:40 +0000293 static QuantumType
294 quantum_types[4] =
295 {
296 RedQuantum,
297 GreenQuantum,
298 BlueQuantum,
299 AlphaQuantum
300 };
301
cristy3ed852e2009-09-05 21:47:34 +0000302 /*
303 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
304 */
cristy90dbac72010-08-22 15:08:40 +0000305 if (LocaleCompare(image_info->magick,"RGBO") == 0)
306 quantum_types[3]=OpacityQuantum;
cristy3ed852e2009-09-05 21:47:34 +0000307 if (scene == 0)
308 {
cristy90dbac72010-08-22 15:08:40 +0000309 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
cristyb3f97ae2015-05-18 12:29:32 +0000310 pixels=(const unsigned char *) ReadBlobStream(image,length,
311 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000312 }
cristybb503372010-05-27 20:51:26 +0000313 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000314 {
cristy17f11b02014-12-20 19:37:04 +0000315 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
cristy3ed852e2009-09-05 21:47:34 +0000316 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100317 register const Quantum
318 *magick_restrict p;
319
320 register Quantum
321 *magick_restrict q;
322
323 register ssize_t
324 x;
325
326 if (count != (ssize_t) length)
327 {
328 status=MagickFalse;
329 ThrowFileException(exception,CorruptImageError,
330 "UnexpectedEndOfFile",image->filename);
331 break;
332 }
cristy90dbac72010-08-22 15:08:40 +0000333 quantum_type=quantum_types[i];
cristy3ed852e2009-09-05 21:47:34 +0000334 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
335 exception);
cristyacd2ed22011-08-30 01:44:23 +0000336 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000337 break;
338 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
cristy90dbac72010-08-22 15:08:40 +0000339 quantum_info,quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +0000340 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
341 break;
Cristy747a7342019-06-03 21:01:22 -0400342 if (((y-image->extract_info.y) >= 0) &&
cristybb503372010-05-27 20:51:26 +0000343 ((y-image->extract_info.y) < (ssize_t) image->rows))
cristy3ed852e2009-09-05 21:47:34 +0000344 {
345 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
346 0,canvas_image->columns,1,exception);
347 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
348 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000349 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy3ed852e2009-09-05 21:47:34 +0000350 break;
cristy90dbac72010-08-22 15:08:40 +0000351 for (x=0; x < (ssize_t) image->columns; x++)
352 {
353 switch (quantum_type)
cristy3ed852e2009-09-05 21:47:34 +0000354 {
cristy90dbac72010-08-22 15:08:40 +0000355 case RedQuantum:
356 {
cristy4c08aed2011-07-01 19:47:50 +0000357 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
cristy90dbac72010-08-22 15:08:40 +0000358 break;
359 }
360 case GreenQuantum:
361 {
cristy4c08aed2011-07-01 19:47:50 +0000362 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
cristy90dbac72010-08-22 15:08:40 +0000363 break;
364 }
365 case BlueQuantum:
366 {
cristy4c08aed2011-07-01 19:47:50 +0000367 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
cristy90dbac72010-08-22 15:08:40 +0000368 break;
369 }
370 case OpacityQuantum:
371 {
Cristyc7737122018-03-09 20:01:16 -0500372 SetPixelOpacity(image,GetPixelOpacity(canvas_image,p),q);
cristy90dbac72010-08-22 15:08:40 +0000373 break;
374 }
375 case AlphaQuantum:
376 {
cristy4c08aed2011-07-01 19:47:50 +0000377 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
cristy90dbac72010-08-22 15:08:40 +0000378 break;
379 }
380 default:
381 break;
cristy3ed852e2009-09-05 21:47:34 +0000382 }
cristyed231572011-07-14 02:18:59 +0000383 p+=GetPixelChannels(canvas_image);
384 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000385 }
cristy3ed852e2009-09-05 21:47:34 +0000386 if (SyncAuthenticPixels(image,exception) == MagickFalse)
387 break;
388 }
cristyb3f97ae2015-05-18 12:29:32 +0000389 pixels=(const unsigned char *) ReadBlobStream(image,length,
390 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000391 }
392 if (image->previous == (Image *) NULL)
393 {
cristycee97112010-05-28 00:44:52 +0000394 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
395 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000396 if (status == MagickFalse)
397 break;
398 }
399 }
400 break;
401 }
402 case PlaneInterlace:
403 {
404 /*
405 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
406 */
407 if (scene == 0)
408 {
cristy90dbac72010-08-22 15:08:40 +0000409 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
cristyb3f97ae2015-05-18 12:29:32 +0000410 pixels=(const unsigned char *) ReadBlobStream(image,length,
411 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000412 }
cristy90dbac72010-08-22 15:08:40 +0000413 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000414 {
cristy4c08aed2011-07-01 19:47:50 +0000415 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100416 *magick_restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000417
cristy4c08aed2011-07-01 19:47:50 +0000418 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100419 *magick_restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000420
cristy90dbac72010-08-22 15:08:40 +0000421 register ssize_t
422 x;
cristy3ed852e2009-09-05 21:47:34 +0000423
cristy90dbac72010-08-22 15:08:40 +0000424 if (count != (ssize_t) length)
cristy3ed852e2009-09-05 21:47:34 +0000425 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100426 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000427 ThrowFileException(exception,CorruptImageError,
428 "UnexpectedEndOfFile",image->filename);
429 break;
430 }
431 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
432 exception);
cristyacd2ed22011-08-30 01:44:23 +0000433 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000434 break;
435 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
436 quantum_info,RedQuantum,pixels,exception);
437 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
438 break;
Cristy747a7342019-06-03 21:01:22 -0400439 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000440 ((y-image->extract_info.y) < (ssize_t) image->rows))
441 {
442 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
443 canvas_image->columns,1,exception);
444 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
445 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000446 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000447 break;
448 for (x=0; x < (ssize_t) image->columns; x++)
449 {
cristy4c08aed2011-07-01 19:47:50 +0000450 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000451 p+=GetPixelChannels(canvas_image);
452 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000453 }
454 if (SyncAuthenticPixels(image,exception) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000455 break;
456 }
cristyb3f97ae2015-05-18 12:29:32 +0000457 pixels=(const unsigned char *) ReadBlobStream(image,length,
458 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000459 }
460 if (image->previous == (Image *) NULL)
461 {
cristy90dbac72010-08-22 15:08:40 +0000462 status=SetImageProgress(image,LoadImageTag,1,6);
463 if (status == MagickFalse)
464 break;
465 }
466 for (y=0; y < (ssize_t) image->extract_info.height; y++)
467 {
cristy4c08aed2011-07-01 19:47:50 +0000468 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100469 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +0000470
cristy4c08aed2011-07-01 19:47:50 +0000471 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100472 *magick_restrict q;
cristy90dbac72010-08-22 15:08:40 +0000473
474 register ssize_t
475 x;
476
477 if (count != (ssize_t) length)
478 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100479 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000480 ThrowFileException(exception,CorruptImageError,
481 "UnexpectedEndOfFile",image->filename);
482 break;
483 }
484 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
485 exception);
cristyacd2ed22011-08-30 01:44:23 +0000486 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000487 break;
488 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
489 quantum_info,GreenQuantum,pixels,exception);
490 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
491 break;
Cristy747a7342019-06-03 21:01:22 -0400492 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000493 ((y-image->extract_info.y) < (ssize_t) image->rows))
494 {
495 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
496 canvas_image->columns,1,exception);
497 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
498 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000499 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000500 break;
501 for (x=0; x < (ssize_t) image->columns; x++)
502 {
cristyf27ee032011-09-29 17:51:41 +0000503 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000504 p+=GetPixelChannels(canvas_image);
505 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000506 }
507 if (SyncAuthenticPixels(image,exception) == MagickFalse)
508 break;
509 }
cristyb3f97ae2015-05-18 12:29:32 +0000510 pixels=(const unsigned char *) ReadBlobStream(image,length,
511 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000512 }
513 if (image->previous == (Image *) NULL)
514 {
515 status=SetImageProgress(image,LoadImageTag,2,6);
516 if (status == MagickFalse)
517 break;
518 }
519 for (y=0; y < (ssize_t) image->extract_info.height; y++)
520 {
cristy4c08aed2011-07-01 19:47:50 +0000521 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100522 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +0000523
cristy4c08aed2011-07-01 19:47:50 +0000524 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100525 *magick_restrict q;
cristy90dbac72010-08-22 15:08:40 +0000526
527 register ssize_t
528 x;
529
530 if (count != (ssize_t) length)
531 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100532 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000533 ThrowFileException(exception,CorruptImageError,
534 "UnexpectedEndOfFile",image->filename);
535 break;
536 }
537 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
538 exception);
cristyacd2ed22011-08-30 01:44:23 +0000539 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000540 break;
541 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
542 quantum_info,BlueQuantum,pixels,exception);
543 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
544 break;
Cristy747a7342019-06-03 21:01:22 -0400545 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000546 ((y-image->extract_info.y) < (ssize_t) image->rows))
547 {
548 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
549 canvas_image->columns,1,exception);
550 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
551 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000552 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000553 break;
554 for (x=0; x < (ssize_t) image->columns; x++)
555 {
cristyf27ee032011-09-29 17:51:41 +0000556 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000557 p+=GetPixelChannels(canvas_image);
558 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000559 }
560 if (SyncAuthenticPixels(image,exception) == MagickFalse)
561 break;
562 }
cristyb3f97ae2015-05-18 12:29:32 +0000563 pixels=(const unsigned char *) ReadBlobStream(image,length,
564 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000565 }
566 if (image->previous == (Image *) NULL)
567 {
cristy90dbac72010-08-22 15:08:40 +0000568 status=SetImageProgress(image,LoadImageTag,4,6);
569 if (status == MagickFalse)
570 break;
571 }
cristy17f11b02014-12-20 19:37:04 +0000572 if (image->alpha_trait != UndefinedPixelTrait)
cristy90dbac72010-08-22 15:08:40 +0000573 {
574 for (y=0; y < (ssize_t) image->extract_info.height; y++)
575 {
cristy4c08aed2011-07-01 19:47:50 +0000576 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100577 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +0000578
cristy4c08aed2011-07-01 19:47:50 +0000579 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100580 *magick_restrict q;
cristy90dbac72010-08-22 15:08:40 +0000581
582 register ssize_t
583 x;
584
585 if (count != (ssize_t) length)
586 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100587 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000588 ThrowFileException(exception,CorruptImageError,
589 "UnexpectedEndOfFile",image->filename);
590 break;
591 }
592 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
593 exception);
cristyacd2ed22011-08-30 01:44:23 +0000594 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000595 break;
596 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
597 quantum_info,AlphaQuantum,pixels,exception);
598 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
599 break;
Cristy747a7342019-06-03 21:01:22 -0400600 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000601 ((y-image->extract_info.y) < (ssize_t) image->rows))
602 {
603 p=GetVirtualPixels(canvas_image,
604 canvas_image->extract_info.x,0,canvas_image->columns,1,
605 exception);
606 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
607 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000608 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000609 break;
610 for (x=0; x < (ssize_t) image->columns; x++)
611 {
cristyf27ee032011-09-29 17:51:41 +0000612 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000613 p+=GetPixelChannels(canvas_image);
614 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000615 }
616 if (SyncAuthenticPixels(image,exception) == MagickFalse)
617 break;
618 }
cristyb3f97ae2015-05-18 12:29:32 +0000619 pixels=(const unsigned char *) ReadBlobStream(image,length,
620 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000621 }
622 if (image->previous == (Image *) NULL)
623 {
624 status=SetImageProgress(image,LoadImageTag,5,6);
625 if (status == MagickFalse)
626 break;
627 }
628 }
629 if (image->previous == (Image *) NULL)
630 {
631 status=SetImageProgress(image,LoadImageTag,6,6);
cristy3ed852e2009-09-05 21:47:34 +0000632 if (status == MagickFalse)
633 break;
634 }
635 break;
636 }
637 case PartitionInterlace:
638 {
639 /*
640 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
641 */
cristy90dbac72010-08-22 15:08:40 +0000642 AppendImageFormat("R",image->filename);
643 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
644 if (status == MagickFalse)
Dirk Lemstradede8402018-03-24 17:51:58 +0100645 break;
Cristyb2d24412018-03-09 19:41:19 -0500646 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
Dirk Lemstradede8402018-03-24 17:51:58 +0100647 {
648 status=MagickFalse;
649 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
650 image->filename);
651 break;
652 }
cristy90dbac72010-08-22 15:08:40 +0000653 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
654 for (i=0; i < (ssize_t) scene; i++)
Dirk Lemstradede8402018-03-24 17:51:58 +0100655 {
cristy90dbac72010-08-22 15:08:40 +0000656 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristybd797f12015-01-24 20:42:32 +0000657 {
cristyb3f97ae2015-05-18 12:29:32 +0000658 pixels=(const unsigned char *) ReadBlobStream(image,length,
659 GetQuantumPixels(quantum_info),&count);
cristybd797f12015-01-24 20:42:32 +0000660 if (count != (ssize_t) length)
Dirk Lemstradede8402018-03-24 17:51:58 +0100661 break;
cristybd797f12015-01-24 20:42:32 +0000662 }
Dirk Lemstradede8402018-03-24 17:51:58 +0100663 if (count != (ssize_t) length)
664 break;
665 }
cristyb3f97ae2015-05-18 12:29:32 +0000666 pixels=(const unsigned char *) ReadBlobStream(image,length,
667 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000668 for (y=0; y < (ssize_t) image->extract_info.height; y++)
669 {
cristy4c08aed2011-07-01 19:47:50 +0000670 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100671 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +0000672
cristy4c08aed2011-07-01 19:47:50 +0000673 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100674 *magick_restrict q;
cristy90dbac72010-08-22 15:08:40 +0000675
676 register ssize_t
677 x;
678
679 if (count != (ssize_t) length)
cristy3ed852e2009-09-05 21:47:34 +0000680 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100681 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000682 ThrowFileException(exception,CorruptImageError,
683 "UnexpectedEndOfFile",image->filename);
684 break;
685 }
686 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
687 exception);
cristyacd2ed22011-08-30 01:44:23 +0000688 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000689 break;
690 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
691 quantum_info,RedQuantum,pixels,exception);
692 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
693 break;
Cristy747a7342019-06-03 21:01:22 -0400694 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000695 ((y-image->extract_info.y) < (ssize_t) image->rows))
696 {
697 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
698 canvas_image->columns,1,exception);
699 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
700 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000701 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000702 break;
703 for (x=0; x < (ssize_t) image->columns; x++)
704 {
cristy4c08aed2011-07-01 19:47:50 +0000705 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000706 p+=GetPixelChannels(canvas_image);
707 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000708 }
709 if (SyncAuthenticPixels(image,exception) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000710 break;
711 }
cristyb3f97ae2015-05-18 12:29:32 +0000712 pixels=(const unsigned char *) ReadBlobStream(image,length,
713 GetQuantumPixels(quantum_info),&count);
cristy3ed852e2009-09-05 21:47:34 +0000714 }
715 if (image->previous == (Image *) NULL)
716 {
cristy90dbac72010-08-22 15:08:40 +0000717 status=SetImageProgress(image,LoadImageTag,1,5);
718 if (status == MagickFalse)
719 break;
720 }
721 (void) CloseBlob(image);
722 AppendImageFormat("G",image->filename);
723 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
724 if (status == MagickFalse)
Dirk Lemstradede8402018-03-24 17:51:58 +0100725 break;
cristy90dbac72010-08-22 15:08:40 +0000726 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
727 for (i=0; i < (ssize_t) scene; i++)
Dirk Lemstradede8402018-03-24 17:51:58 +0100728 {
cristy90dbac72010-08-22 15:08:40 +0000729 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristybd797f12015-01-24 20:42:32 +0000730 {
cristyb3f97ae2015-05-18 12:29:32 +0000731 pixels=(const unsigned char *) ReadBlobStream(image,length,
732 GetQuantumPixels(quantum_info),&count);
cristybd797f12015-01-24 20:42:32 +0000733 if (count != (ssize_t) length)
Dirk Lemstradede8402018-03-24 17:51:58 +0100734 break;
cristybd797f12015-01-24 20:42:32 +0000735 }
Dirk Lemstradede8402018-03-24 17:51:58 +0100736 if (count != (ssize_t) length)
737 break;
738 }
cristyb3f97ae2015-05-18 12:29:32 +0000739 pixels=(const unsigned char *) ReadBlobStream(image,length,
740 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000741 for (y=0; y < (ssize_t) image->extract_info.height; y++)
742 {
cristy4c08aed2011-07-01 19:47:50 +0000743 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100744 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +0000745
cristy4c08aed2011-07-01 19:47:50 +0000746 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100747 *magick_restrict q;
cristy90dbac72010-08-22 15:08:40 +0000748
749 register ssize_t
750 x;
751
752 if (count != (ssize_t) length)
753 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100754 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000755 ThrowFileException(exception,CorruptImageError,
756 "UnexpectedEndOfFile",image->filename);
757 break;
758 }
759 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
760 exception);
cristyacd2ed22011-08-30 01:44:23 +0000761 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000762 break;
763 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
764 quantum_info,GreenQuantum,pixels,exception);
765 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
766 break;
Cristy747a7342019-06-03 21:01:22 -0400767 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000768 ((y-image->extract_info.y) < (ssize_t) image->rows))
769 {
770 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
771 canvas_image->columns,1,exception);
772 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
773 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000774 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000775 break;
776 for (x=0; x < (ssize_t) image->columns; x++)
777 {
cristyf27ee032011-09-29 17:51:41 +0000778 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000779 p+=GetPixelChannels(canvas_image);
780 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000781 }
782 if (SyncAuthenticPixels(image,exception) == MagickFalse)
783 break;
784 }
cristyb3f97ae2015-05-18 12:29:32 +0000785 pixels=(const unsigned char *) ReadBlobStream(image,length,
786 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000787 }
788 if (image->previous == (Image *) NULL)
789 {
790 status=SetImageProgress(image,LoadImageTag,2,5);
791 if (status == MagickFalse)
792 break;
793 }
794 (void) CloseBlob(image);
795 AppendImageFormat("B",image->filename);
796 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
797 if (status == MagickFalse)
Dirk Lemstradede8402018-03-24 17:51:58 +0100798 break;
cristy90dbac72010-08-22 15:08:40 +0000799 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
800 for (i=0; i < (ssize_t) scene; i++)
Dirk Lemstradede8402018-03-24 17:51:58 +0100801 {
cristy90dbac72010-08-22 15:08:40 +0000802 for (y=0; y < (ssize_t) image->extract_info.height; y++)
Cristy747a7342019-06-03 21:01:22 -0400803 {
cristyb3f97ae2015-05-18 12:29:32 +0000804 pixels=(const unsigned char *) ReadBlobStream(image,length,
805 GetQuantumPixels(quantum_info),&count);
cristybd797f12015-01-24 20:42:32 +0000806 if (count != (ssize_t) length)
Dirk Lemstradede8402018-03-24 17:51:58 +0100807 break;
808 }
809 if (count != (ssize_t) length)
810 break;
811 }
cristyb3f97ae2015-05-18 12:29:32 +0000812 pixels=(const unsigned char *) ReadBlobStream(image,length,
813 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000814 for (y=0; y < (ssize_t) image->extract_info.height; y++)
815 {
cristy4c08aed2011-07-01 19:47:50 +0000816 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100817 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +0000818
cristy4c08aed2011-07-01 19:47:50 +0000819 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100820 *magick_restrict q;
cristy90dbac72010-08-22 15:08:40 +0000821
822 register ssize_t
823 x;
824
825 if (count != (ssize_t) length)
826 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100827 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000828 ThrowFileException(exception,CorruptImageError,
829 "UnexpectedEndOfFile",image->filename);
830 break;
831 }
832 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
833 exception);
cristyacd2ed22011-08-30 01:44:23 +0000834 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000835 break;
836 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
837 quantum_info,BlueQuantum,pixels,exception);
838 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
839 break;
Cristy747a7342019-06-03 21:01:22 -0400840 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000841 ((y-image->extract_info.y) < (ssize_t) image->rows))
842 {
843 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
844 canvas_image->columns,1,exception);
845 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
846 image->columns,1,exception);
cristyddacdd12012-05-07 23:08:14 +0000847 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000848 break;
849 for (x=0; x < (ssize_t) image->columns; x++)
850 {
cristyf27ee032011-09-29 17:51:41 +0000851 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000852 p+=GetPixelChannels(canvas_image);
853 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000854 }
855 if (SyncAuthenticPixels(image,exception) == MagickFalse)
856 break;
857 }
cristyb3f97ae2015-05-18 12:29:32 +0000858 pixels=(const unsigned char *) ReadBlobStream(image,length,
859 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000860 }
861 if (image->previous == (Image *) NULL)
862 {
863 status=SetImageProgress(image,LoadImageTag,3,5);
864 if (status == MagickFalse)
865 break;
866 }
cristy17f11b02014-12-20 19:37:04 +0000867 if (image->alpha_trait != UndefinedPixelTrait)
cristy90dbac72010-08-22 15:08:40 +0000868 {
869 (void) CloseBlob(image);
870 AppendImageFormat("A",image->filename);
871 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
872 if (status == MagickFalse)
Dirk Lemstradede8402018-03-24 17:51:58 +0100873 break;
cristy90dbac72010-08-22 15:08:40 +0000874 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
875 for (i=0; i < (ssize_t) scene; i++)
Dirk Lemstradede8402018-03-24 17:51:58 +0100876 {
cristy90dbac72010-08-22 15:08:40 +0000877 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristybd797f12015-01-24 20:42:32 +0000878 {
cristyb3f97ae2015-05-18 12:29:32 +0000879 pixels=(const unsigned char *) ReadBlobStream(image,length,
cristybd797f12015-01-24 20:42:32 +0000880 GetQuantumPixels(quantum_info),&count);
881 if (count != (ssize_t) length)
Dirk Lemstradede8402018-03-24 17:51:58 +0100882 break;
cristybd797f12015-01-24 20:42:32 +0000883 }
Dirk Lemstradede8402018-03-24 17:51:58 +0100884 if (count != (ssize_t) length)
885 break;
886 }
cristyb3f97ae2015-05-18 12:29:32 +0000887 pixels=(const unsigned char *) ReadBlobStream(image,length,
888 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000889 for (y=0; y < (ssize_t) image->extract_info.height; y++)
890 {
cristy4c08aed2011-07-01 19:47:50 +0000891 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100892 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +0000893
cristy4c08aed2011-07-01 19:47:50 +0000894 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100895 *magick_restrict q;
cristy90dbac72010-08-22 15:08:40 +0000896
897 register ssize_t
898 x;
899
900 if (count != (ssize_t) length)
901 {
Dirk Lemstradede8402018-03-24 17:51:58 +0100902 status=MagickFalse;
cristy90dbac72010-08-22 15:08:40 +0000903 ThrowFileException(exception,CorruptImageError,
904 "UnexpectedEndOfFile",image->filename);
905 break;
906 }
907 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
908 exception);
cristyacd2ed22011-08-30 01:44:23 +0000909 if (q == (Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +0000910 break;
911 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
912 quantum_info,BlueQuantum,pixels,exception);
913 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
914 break;
Cristy747a7342019-06-03 21:01:22 -0400915 if (((y-image->extract_info.y) >= 0) &&
cristy90dbac72010-08-22 15:08:40 +0000916 ((y-image->extract_info.y) < (ssize_t) image->rows))
917 {
918 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
919 0,canvas_image->columns,1,exception);
920 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
921 image->columns,1,exception);
cristyc6aebff2012-05-07 23:24:35 +0000922 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
cristy90dbac72010-08-22 15:08:40 +0000923 break;
924 for (x=0; x < (ssize_t) image->columns; x++)
925 {
cristyf27ee032011-09-29 17:51:41 +0000926 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
cristyed231572011-07-14 02:18:59 +0000927 p+=GetPixelChannels(canvas_image);
928 q+=GetPixelChannels(image);
cristy90dbac72010-08-22 15:08:40 +0000929 }
930 if (SyncAuthenticPixels(image,exception) == MagickFalse)
931 break;
932 }
cristyb3f97ae2015-05-18 12:29:32 +0000933 pixels=(const unsigned char *) ReadBlobStream(image,length,
934 GetQuantumPixels(quantum_info),&count);
cristy90dbac72010-08-22 15:08:40 +0000935 }
936 if (image->previous == (Image *) NULL)
937 {
938 status=SetImageProgress(image,LoadImageTag,4,5);
939 if (status == MagickFalse)
940 break;
941 }
942 }
943 (void) CloseBlob(image);
944 if (image->previous == (Image *) NULL)
945 {
cristy3ed852e2009-09-05 21:47:34 +0000946 status=SetImageProgress(image,LoadImageTag,5,5);
947 if (status == MagickFalse)
948 break;
949 }
950 break;
951 }
952 }
Dirk Lemstradede8402018-03-24 17:51:58 +0100953 if (status == MagickFalse)
954 break;
cristy3ed852e2009-09-05 21:47:34 +0000955 SetQuantumImageType(image,quantum_type);
cristy3ed852e2009-09-05 21:47:34 +0000956 /*
957 Proceed to next image.
958 */
959 if (image_info->number_scenes != 0)
960 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
961 break;
962 if (count == (ssize_t) length)
963 {
964 /*
965 Allocate next image structure.
966 */
cristy9950d572011-10-01 18:22:35 +0000967 AcquireNextImage(image_info,image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000968 if (GetNextImageInList(image) == (Image *) NULL)
969 {
Cristy5ff0db92018-06-20 18:04:36 -0400970 status=MagickFalse;
971 break;
cristy3ed852e2009-09-05 21:47:34 +0000972 }
973 image=SyncNextImageInList(image);
974 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
975 GetBlobSize(image));
976 if (status == MagickFalse)
977 break;
978 }
979 scene++;
980 } while (count == (ssize_t) length);
cristy3ed852e2009-09-05 21:47:34 +0000981 quantum_info=DestroyQuantumInfo(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000982 canvas_image=DestroyImage(canvas_image);
983 (void) CloseBlob(image);
Dirk Lemstradede8402018-03-24 17:51:58 +0100984 if (status == MagickFalse)
Cristy3b48d202018-07-01 17:11:51 -0400985 return(DestroyImageList(image));
cristy3ed852e2009-09-05 21:47:34 +0000986 return(GetFirstImageInList(image));
987}
988
989/*
990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991% %
992% %
993% %
Cristy747a7342019-06-03 21:01:22 -0400994% R e a d R G B 5 6 5 I m a g e %
995% %
996% %
997% %
998%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
999%
1000% ReadGRAYImage() reads an image of raw RGB 5-6-5 samples and returns it. It
1001% allocates the memory necessary for the new Image structure and returns a
1002% pointer to the new image.
1003%
1004% The format of the ReadGRAYImage method is:
1005%
1006% Image *ReadGRAYImage(const ImageInfo *image_info,
1007% ExceptionInfo *exception)
1008%
1009% A description of each parameter follows:
1010%
1011% o image_info: the image info.
1012%
1013% o exception: return any errors or warnings in this structure.
1014%
1015*/
1016static Image *ReadRGB565Image(const ImageInfo *image_info,
1017 ExceptionInfo *exception)
1018{
1019 const unsigned char
1020 *pixels;
1021
1022 Image
1023 *canvas_image,
1024 *image;
1025
1026 MagickBooleanType
1027 status;
1028
1029 MagickOffsetType
1030 scene;
1031
1032 QuantumInfo
1033 *quantum_info;
1034
1035 QuantumType
1036 quantum_type;
1037
1038 size_t
1039 length;
1040
1041 ssize_t
1042 count,
1043 y;
1044
1045 /*
1046 Open image file.
1047 */
1048 assert(image_info != (const ImageInfo *) NULL);
1049 assert(image_info->signature == MagickCoreSignature);
1050 if (image_info->debug != MagickFalse)
1051 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1052 image_info->filename);
1053 assert(exception != (ExceptionInfo *) NULL);
1054 assert(exception->signature == MagickCoreSignature);
1055 image=AcquireImage(image_info,exception);
1056 if ((image->columns == 0) || (image->rows == 0))
1057 ThrowReaderException(OptionError,"MustSpecifyImageSize");
1058 image->depth=16;
1059 if (image_info->interlace != PartitionInterlace)
1060 {
1061 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
1062 if (status == MagickFalse)
1063 {
1064 image=DestroyImageList(image);
1065 return((Image *) NULL);
1066 }
1067 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
1068 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
1069 image->filename);
1070 }
1071 /*
1072 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
1073 */
1074 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
1075 exception);
1076 if(canvas_image == (Image *) NULL)
1077 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1078 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
1079 exception);
1080 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
1081 if (quantum_info == (QuantumInfo *) NULL)
1082 {
1083 canvas_image=DestroyImage(canvas_image);
1084 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1085 }
1086 quantum_type=GrayQuantum;
1087 pixels=(const unsigned char *) NULL;
1088 if (image_info->number_scenes != 0)
1089 while (image->scene < image_info->scene)
1090 {
1091 /*
1092 Skip to next image.
1093 */
1094 image->scene++;
1095 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
1096 for (y=0; y < (ssize_t) image->rows; y++)
1097 {
1098 pixels=(const unsigned char *) ReadBlobStream(image,length,
1099 GetQuantumPixels(quantum_info),&count);
1100 if (count != (ssize_t) length)
1101 break;
1102 }
1103 }
1104 count=0;
1105 length=0;
1106 scene=0;
1107 status=MagickTrue;
1108 do
1109 {
1110 /*
1111 Read pixels to virtual canvas image then push to image.
1112 */
1113 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
1114 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1115 break;
1116 status=SetImageExtent(image,image->columns,image->rows,exception);
1117 if (status == MagickFalse)
1118 break;
1119 /*
1120 No interlacing: GGG...
1121 */
1122 if (scene == 0)
1123 {
1124 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
1125 pixels=(const unsigned char *) ReadBlobStream(image,length,
1126 GetQuantumPixels(quantum_info),&count);
1127 }
1128 for (y=0; y < (ssize_t) image->extract_info.height; y++)
1129 {
1130 register const Quantum
1131 *magick_restrict p;
1132
1133 register Quantum
1134 *magick_restrict q;
1135
1136 register ssize_t
1137 x;
1138
1139 if (count != (ssize_t) length)
1140 {
1141 status=MagickFalse;
1142 ThrowFileException(exception,CorruptImageError,
1143 "UnexpectedEndOfFile",image->filename);
1144 break;
1145 }
1146 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,exception);
1147 if (q == (Quantum *) NULL)
1148 break;
1149 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
1150 quantum_info,quantum_type,pixels,exception);
1151 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
1152 break;
1153 if (((y-image->extract_info.y) >= 0) &&
1154 ((y-image->extract_info.y) < (ssize_t) image->rows))
1155 {
1156 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
1157 canvas_image->columns,1,exception);
1158 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
1159 image->columns,1,exception);
1160 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
1161 break;
1162 for (x=0; x < (ssize_t) image->columns; x++)
1163 {
1164 unsigned short
1165 pixel;
1166
1167 pixel=(unsigned short) ScaleQuantumToShort(GetPixelGray(
1168 canvas_image,p));
1169 SetPixelRed(image,(Quantum) (((pixel >> 11) & 0x1f) << 11),q);
1170 SetPixelGreen(image,(Quantum) (((pixel >> 5) & 0x3f) << 10),q);
1171 SetPixelBlue(image,(Quantum) ((pixel & 0x1f) << 11),q);
1172 p+=GetPixelChannels(canvas_image);
1173 q+=GetPixelChannels(image);
1174 }
1175 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1176 break;
1177 }
1178 if (image->previous == (Image *) NULL)
1179 {
1180 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
1181 image->rows);
1182 if (status == MagickFalse)
1183 break;
1184 }
1185 pixels=(const unsigned char *) ReadBlobStream(image,length,
1186 GetQuantumPixels(quantum_info),&count);
1187 }
1188 if (status == MagickFalse)
1189 break;
1190 SetQuantumImageType(image,quantum_type);
1191 /*
1192 Proceed to next image.
1193 */
1194 if (image_info->number_scenes != 0)
1195 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1196 break;
1197 if (count == (ssize_t) length)
1198 {
1199 /*
1200 Allocate next image structure.
1201 */
1202 AcquireNextImage(image_info,image,exception);
1203 if (GetNextImageInList(image) == (Image *) NULL)
1204 {
1205 status=MagickFalse;
1206 break;
1207 }
1208 image=SyncNextImageInList(image);
1209 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1210 GetBlobSize(image));
1211 if (status == MagickFalse)
1212 break;
1213 }
1214 scene++;
1215 } while (count == (ssize_t) length);
1216 quantum_info=DestroyQuantumInfo(quantum_info);
1217 canvas_image=DestroyImage(canvas_image);
1218 (void) CloseBlob(image);
1219 if (status == MagickFalse)
1220 return(DestroyImageList(image));
1221 return(GetFirstImageInList(image));
1222}
1223
1224/*
1225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226% %
1227% %
1228% %
cristy3ed852e2009-09-05 21:47:34 +00001229% R e g i s t e r R G B I m a g e %
1230% %
1231% %
1232% %
1233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1234%
cristy90dbac72010-08-22 15:08:40 +00001235% RegisterRGBImage() adds attributes for the RGB image format to
cristy3ed852e2009-09-05 21:47:34 +00001236% the list of supported formats. The attributes include the image format
1237% tag, a method to read and/or write the format, whether the format
1238% supports the saving of more than one frame to the same file or blob,
1239% whether the format supports native in-memory I/O, and a brief
1240% description of the format.
1241%
1242% The format of the RegisterRGBImage method is:
1243%
cristybb503372010-05-27 20:51:26 +00001244% size_t RegisterRGBImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001245%
1246*/
cristybb503372010-05-27 20:51:26 +00001247ModuleExport size_t RegisterRGBImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001248{
1249 MagickInfo
1250 *entry;
1251
dirk06b627a2015-04-06 18:59:17 +00001252 entry=AcquireMagickInfo("RGB","RGB",
1253 "Raw red, green, and blue samples");
cristy3ed852e2009-09-05 21:47:34 +00001254 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1255 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
dirk08e9a112015-02-22 01:51:41 +00001256 entry->flags|=CoderRawSupportFlag;
1257 entry->flags|=CoderEndianSupportFlag;
cristy3ed852e2009-09-05 21:47:34 +00001258 (void) RegisterMagickInfo(entry);
dirk06b627a2015-04-06 18:59:17 +00001259 entry=AcquireMagickInfo("RGB","RGBA",
1260 "Raw red, green, blue, and alpha samples");
cristy3ed852e2009-09-05 21:47:34 +00001261 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1262 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
dirk08e9a112015-02-22 01:51:41 +00001263 entry->flags|=CoderRawSupportFlag;
1264 entry->flags|=CoderEndianSupportFlag;
cristy3ed852e2009-09-05 21:47:34 +00001265 (void) RegisterMagickInfo(entry);
dirk06b627a2015-04-06 18:59:17 +00001266 entry=AcquireMagickInfo("RGB","RGBO",
1267 "Raw red, green, blue, and opacity samples");
cristy3ed852e2009-09-05 21:47:34 +00001268 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1269 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
dirk08e9a112015-02-22 01:51:41 +00001270 entry->flags|=CoderRawSupportFlag;
1271 entry->flags|=CoderEndianSupportFlag;
cristy3ed852e2009-09-05 21:47:34 +00001272 (void) RegisterMagickInfo(entry);
Cristy747a7342019-06-03 21:01:22 -04001273 entry=AcquireMagickInfo("RGB","RGB565",
Dirk Lemstra98bffc22019-06-09 07:23:35 +02001274 "Raw red, green, blue samples in 565 format");
Cristy747a7342019-06-03 21:01:22 -04001275 entry->decoder=(DecodeImageHandler *) ReadRGB565Image;
1276 entry->flags|=CoderRawSupportFlag;
1277 entry->flags|=CoderEndianSupportFlag;
1278 (void) RegisterMagickInfo(entry);
cristy3ed852e2009-09-05 21:47:34 +00001279 return(MagickImageCoderSignature);
1280}
1281
1282/*
1283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1284% %
1285% %
1286% %
1287% U n r e g i s t e r R G B I m a g e %
1288% %
1289% %
1290% %
1291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1292%
cristy90dbac72010-08-22 15:08:40 +00001293% UnregisterRGBImage() removes format registrations made by the RGB module
1294% from the list of supported formats.
cristy3ed852e2009-09-05 21:47:34 +00001295%
1296% The format of the UnregisterRGBImage method is:
1297%
1298% UnregisterRGBImage(void)
1299%
1300*/
1301ModuleExport void UnregisterRGBImage(void)
1302{
1303 (void) UnregisterMagickInfo("RGBO");
1304 (void) UnregisterMagickInfo("RGBA");
cristy3ed852e2009-09-05 21:47:34 +00001305 (void) UnregisterMagickInfo("RGB");
1306}
1307
1308/*
1309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1310% %
1311% %
1312% %
1313% W r i t e R G B I m a g e %
1314% %
1315% %
1316% %
1317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318%
cristy90dbac72010-08-22 15:08:40 +00001319% WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1320% rasterfile format.
cristy3ed852e2009-09-05 21:47:34 +00001321%
1322% The format of the WriteRGBImage method is:
1323%
cristy90dbac72010-08-22 15:08:40 +00001324% MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
cristy3a37efd2011-08-28 20:31:03 +00001325% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001326%
1327% A description of each parameter follows.
1328%
1329% o image_info: the image info.
1330%
1331% o image: The image.
1332%
cristy3a37efd2011-08-28 20:31:03 +00001333% o exception: return any errors or warnings in this structure.
1334%
cristy3ed852e2009-09-05 21:47:34 +00001335*/
cristyc6aebff2012-05-07 23:24:35 +00001336static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1337 Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001338{
cristy3ed852e2009-09-05 21:47:34 +00001339 MagickBooleanType
1340 status;
1341
1342 MagickOffsetType
1343 scene;
1344
1345 QuantumInfo
1346 *quantum_info;
1347
1348 QuantumType
cristy90dbac72010-08-22 15:08:40 +00001349 quantum_type;
cristy3ed852e2009-09-05 21:47:34 +00001350
cristyc6da28e2011-04-28 01:41:35 +00001351 size_t
Cristyc45b2bb2018-04-07 12:32:12 -04001352 imageListLength,
cristyc6da28e2011-04-28 01:41:35 +00001353 length;
1354
cristy3ed852e2009-09-05 21:47:34 +00001355 ssize_t
cristy90dbac72010-08-22 15:08:40 +00001356 count,
1357 y;
cristy3ed852e2009-09-05 21:47:34 +00001358
cristy3ed852e2009-09-05 21:47:34 +00001359 unsigned char
1360 *pixels;
1361
cristy3ed852e2009-09-05 21:47:34 +00001362 /*
1363 Allocate memory for pixels.
1364 */
1365 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001366 assert(image_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001367 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001368 assert(image->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001369 if (image->debug != MagickFalse)
1370 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1371 if (image_info->interlace != PartitionInterlace)
1372 {
1373 /*
1374 Open output image file.
1375 */
cristyedf03fa2011-08-30 12:44:39 +00001376 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
cristy3ed852e2009-09-05 21:47:34 +00001377 if (status == MagickFalse)
1378 return(status);
1379 }
1380 quantum_type=RGBQuantum;
cristy90dbac72010-08-22 15:08:40 +00001381 if (LocaleCompare(image_info->magick,"RGBA") == 0)
cristyc6aebff2012-05-07 23:24:35 +00001382 quantum_type=RGBAQuantum;
cristy90dbac72010-08-22 15:08:40 +00001383 if (LocaleCompare(image_info->magick,"RGBO") == 0)
cristyc6aebff2012-05-07 23:24:35 +00001384 quantum_type=RGBOQuantum;
cristy3ed852e2009-09-05 21:47:34 +00001385 scene=0;
Cristyc45b2bb2018-04-07 12:32:12 -04001386 imageListLength=GetImageListLength(image);
cristy3ed852e2009-09-05 21:47:34 +00001387 do
1388 {
1389 /*
1390 Convert MIFF to RGB raster pixels.
1391 */
cristyaf8d3912014-02-21 14:50:33 +00001392 (void) TransformImageColorspace(image,sRGBColorspace,exception);
cristy3ed852e2009-09-05 21:47:34 +00001393 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
cristy17f11b02014-12-20 19:37:04 +00001394 (image->alpha_trait == UndefinedPixelTrait))
cristy3a37efd2011-08-28 20:31:03 +00001395 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
cristy5f766ef2014-12-14 21:12:47 +00001396 quantum_info=AcquireQuantumInfo(image_info,image);
cristy3ed852e2009-09-05 21:47:34 +00001397 if (quantum_info == (QuantumInfo *) NULL)
1398 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
cristyb3f97ae2015-05-18 12:29:32 +00001399 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +00001400 switch (image_info->interlace)
1401 {
1402 case NoInterlace:
1403 default:
1404 {
cristy3ed852e2009-09-05 21:47:34 +00001405 /*
1406 No interlacing: RGBRGBRGBRGBRGBRGB...
1407 */
cristybb503372010-05-27 20:51:26 +00001408 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001409 {
cristy4c08aed2011-07-01 19:47:50 +00001410 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001411 *magick_restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001412
cristy3a37efd2011-08-28 20:31:03 +00001413 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001414 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001415 break;
cristy4c08aed2011-07-01 19:47:50 +00001416 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001417 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00001418 count=WriteBlob(image,length,pixels);
1419 if (count != (ssize_t) length)
1420 break;
1421 if (image->previous == (Image *) NULL)
1422 {
cristycee97112010-05-28 00:44:52 +00001423 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1424 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001425 if (status == MagickFalse)
1426 break;
1427 }
1428 }
cristy3ed852e2009-09-05 21:47:34 +00001429 break;
1430 }
1431 case LineInterlace:
1432 {
1433 /*
1434 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1435 */
cristybb503372010-05-27 20:51:26 +00001436 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001437 {
cristy4c08aed2011-07-01 19:47:50 +00001438 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001439 *magick_restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001440
cristy3a37efd2011-08-28 20:31:03 +00001441 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001442 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001443 break;
cristy4c08aed2011-07-01 19:47:50 +00001444 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001445 RedQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001446 count=WriteBlob(image,length,pixels);
1447 if (count != (ssize_t) length)
1448 break;
cristy4c08aed2011-07-01 19:47:50 +00001449 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001450 GreenQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001451 count=WriteBlob(image,length,pixels);
1452 if (count != (ssize_t) length)
1453 break;
cristy4c08aed2011-07-01 19:47:50 +00001454 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001455 BlueQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001456 count=WriteBlob(image,length,pixels);
1457 if (count != (ssize_t) length)
1458 break;
1459 if (quantum_type == RGBAQuantum)
1460 {
cristy4c08aed2011-07-01 19:47:50 +00001461 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001462 AlphaQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001463 count=WriteBlob(image,length,pixels);
1464 if (count != (ssize_t) length)
1465 break;
1466 }
1467 if (quantum_type == RGBOQuantum)
1468 {
cristy4c08aed2011-07-01 19:47:50 +00001469 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001470 OpacityQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001471 count=WriteBlob(image,length,pixels);
1472 if (count != (ssize_t) length)
1473 break;
1474 }
cristy3ed852e2009-09-05 21:47:34 +00001475 if (image->previous == (Image *) NULL)
1476 {
cristycee97112010-05-28 00:44:52 +00001477 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1478 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001479 if (status == MagickFalse)
1480 break;
1481 }
1482 }
1483 break;
1484 }
1485 case PlaneInterlace:
1486 {
1487 /*
1488 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1489 */
cristy90dbac72010-08-22 15:08:40 +00001490 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001491 {
cristy4c08aed2011-07-01 19:47:50 +00001492 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001493 *magick_restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001494
cristy3a37efd2011-08-28 20:31:03 +00001495 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001496 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001497 break;
cristy4c08aed2011-07-01 19:47:50 +00001498 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001499 RedQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001500 count=WriteBlob(image,length,pixels);
1501 if (count != (ssize_t) length)
1502 break;
cristy3ed852e2009-09-05 21:47:34 +00001503 }
1504 if (image->previous == (Image *) NULL)
1505 {
cristy90dbac72010-08-22 15:08:40 +00001506 status=SetImageProgress(image,SaveImageTag,1,6);
1507 if (status == MagickFalse)
1508 break;
1509 }
1510 for (y=0; y < (ssize_t) image->rows; y++)
1511 {
cristy4c08aed2011-07-01 19:47:50 +00001512 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001513 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +00001514
cristy3a37efd2011-08-28 20:31:03 +00001515 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001516 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001517 break;
cristy4c08aed2011-07-01 19:47:50 +00001518 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001519 GreenQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001520 count=WriteBlob(image,length,pixels);
1521 if (count != (ssize_t) length)
1522 break;
1523 }
1524 if (image->previous == (Image *) NULL)
1525 {
1526 status=SetImageProgress(image,SaveImageTag,2,6);
1527 if (status == MagickFalse)
1528 break;
1529 }
1530 for (y=0; y < (ssize_t) image->rows; y++)
1531 {
cristy4c08aed2011-07-01 19:47:50 +00001532 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001533 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +00001534
cristy3a37efd2011-08-28 20:31:03 +00001535 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001536 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001537 break;
cristy4c08aed2011-07-01 19:47:50 +00001538 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001539 BlueQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001540 count=WriteBlob(image,length,pixels);
1541 if (count != (ssize_t) length)
1542 break;
1543 }
1544 if (image->previous == (Image *) NULL)
1545 {
1546 status=SetImageProgress(image,SaveImageTag,3,6);
1547 if (status == MagickFalse)
1548 break;
1549 }
1550 if (quantum_type == RGBAQuantum)
1551 {
1552 for (y=0; y < (ssize_t) image->rows; y++)
1553 {
cristy4c08aed2011-07-01 19:47:50 +00001554 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001555 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +00001556
cristy3a37efd2011-08-28 20:31:03 +00001557 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001558 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001559 break;
cristy4c08aed2011-07-01 19:47:50 +00001560 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001561 AlphaQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001562 count=WriteBlob(image,length,pixels);
1563 if (count != (ssize_t) length)
1564 break;
1565 }
1566 if (image->previous == (Image *) NULL)
1567 {
1568 status=SetImageProgress(image,SaveImageTag,5,6);
1569 if (status == MagickFalse)
1570 break;
1571 }
1572 }
1573 if (image_info->interlace == PartitionInterlace)
1574 (void) CopyMagickString(image->filename,image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00001575 MagickPathExtent);
cristy90dbac72010-08-22 15:08:40 +00001576 if (image->previous == (Image *) NULL)
1577 {
1578 status=SetImageProgress(image,SaveImageTag,6,6);
cristy3ed852e2009-09-05 21:47:34 +00001579 if (status == MagickFalse)
1580 break;
1581 }
1582 break;
1583 }
1584 case PartitionInterlace:
1585 {
cristy3ed852e2009-09-05 21:47:34 +00001586 /*
1587 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1588 */
cristy90dbac72010-08-22 15:08:40 +00001589 AppendImageFormat("R",image->filename);
1590 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
cristy3a37efd2011-08-28 20:31:03 +00001591 AppendBinaryBlobMode,exception);
cristy90dbac72010-08-22 15:08:40 +00001592 if (status == MagickFalse)
1593 return(status);
1594 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001595 {
cristy4c08aed2011-07-01 19:47:50 +00001596 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001597 *magick_restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001598
cristy3a37efd2011-08-28 20:31:03 +00001599 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001600 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001601 break;
cristy4c08aed2011-07-01 19:47:50 +00001602 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001603 RedQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001604 count=WriteBlob(image,length,pixels);
1605 if (count != (ssize_t) length)
1606 break;
1607 }
1608 if (image->previous == (Image *) NULL)
1609 {
1610 status=SetImageProgress(image,SaveImageTag,1,6);
1611 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001612 break;
1613 }
cristy90dbac72010-08-22 15:08:40 +00001614 (void) CloseBlob(image);
1615 AppendImageFormat("G",image->filename);
1616 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
cristy3a37efd2011-08-28 20:31:03 +00001617 AppendBinaryBlobMode,exception);
cristy90dbac72010-08-22 15:08:40 +00001618 if (status == MagickFalse)
1619 return(status);
1620 for (y=0; y < (ssize_t) image->rows; y++)
1621 {
cristy4c08aed2011-07-01 19:47:50 +00001622 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001623 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +00001624
cristy3a37efd2011-08-28 20:31:03 +00001625 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001626 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001627 break;
cristy4c08aed2011-07-01 19:47:50 +00001628 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001629 GreenQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001630 count=WriteBlob(image,length,pixels);
1631 if (count != (ssize_t) length)
1632 break;
1633 }
1634 if (image->previous == (Image *) NULL)
1635 {
1636 status=SetImageProgress(image,SaveImageTag,2,6);
1637 if (status == MagickFalse)
1638 break;
1639 }
1640 (void) CloseBlob(image);
1641 AppendImageFormat("B",image->filename);
1642 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
cristy3a37efd2011-08-28 20:31:03 +00001643 AppendBinaryBlobMode,exception);
cristy90dbac72010-08-22 15:08:40 +00001644 if (status == MagickFalse)
1645 return(status);
1646 for (y=0; y < (ssize_t) image->rows; y++)
1647 {
cristy4c08aed2011-07-01 19:47:50 +00001648 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001649 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +00001650
cristy3a37efd2011-08-28 20:31:03 +00001651 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001652 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001653 break;
cristy4c08aed2011-07-01 19:47:50 +00001654 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001655 BlueQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001656 count=WriteBlob(image,length,pixels);
1657 if (count != (ssize_t) length)
1658 break;
1659 }
1660 if (image->previous == (Image *) NULL)
1661 {
1662 status=SetImageProgress(image,SaveImageTag,3,6);
1663 if (status == MagickFalse)
1664 break;
1665 }
cristy90dbac72010-08-22 15:08:40 +00001666 if (quantum_type == RGBAQuantum)
1667 {
1668 (void) CloseBlob(image);
1669 AppendImageFormat("A",image->filename);
1670 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
cristy3a37efd2011-08-28 20:31:03 +00001671 AppendBinaryBlobMode,exception);
cristy90dbac72010-08-22 15:08:40 +00001672 if (status == MagickFalse)
1673 return(status);
1674 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001675 {
cristy4c08aed2011-07-01 19:47:50 +00001676 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001677 *magick_restrict p;
cristy90dbac72010-08-22 15:08:40 +00001678
cristy3a37efd2011-08-28 20:31:03 +00001679 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001680 if (p == (const Quantum *) NULL)
cristy90dbac72010-08-22 15:08:40 +00001681 break;
cristy4c08aed2011-07-01 19:47:50 +00001682 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3a37efd2011-08-28 20:31:03 +00001683 AlphaQuantum,pixels,exception);
cristy90dbac72010-08-22 15:08:40 +00001684 count=WriteBlob(image,length,pixels);
1685 if (count != (ssize_t) length)
cristy3ed852e2009-09-05 21:47:34 +00001686 break;
1687 }
cristy90dbac72010-08-22 15:08:40 +00001688 if (image->previous == (Image *) NULL)
1689 {
1690 status=SetImageProgress(image,SaveImageTag,5,6);
1691 if (status == MagickFalse)
1692 break;
1693 }
1694 }
1695 (void) CloseBlob(image);
cristy3ed852e2009-09-05 21:47:34 +00001696 (void) CopyMagickString(image->filename,image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00001697 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00001698 if (image->previous == (Image *) NULL)
1699 {
cristy90dbac72010-08-22 15:08:40 +00001700 status=SetImageProgress(image,SaveImageTag,6,6);
cristy3ed852e2009-09-05 21:47:34 +00001701 if (status == MagickFalse)
1702 break;
1703 }
1704 break;
1705 }
1706 }
1707 quantum_info=DestroyQuantumInfo(quantum_info);
1708 if (GetNextImageInList(image) == (Image *) NULL)
1709 break;
1710 image=SyncNextImageInList(image);
Cristyc45b2bb2018-04-07 12:32:12 -04001711 status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
cristy3ed852e2009-09-05 21:47:34 +00001712 if (status == MagickFalse)
1713 break;
1714 } while (image_info->adjoin != MagickFalse);
1715 (void) CloseBlob(image);
1716 return(MagickTrue);
1717}