1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % DDDD EEEEE PPPP RRRR EEEEE CCCC AAA TTTTT EEEEE %
7 % D D E P P R R E C A A T E %
8 % D D EEE PPPPP RRRR EEE C AAAAA T EEE %
9 % D D E P R R E C A A T E %
10 % DDDD EEEEE P R R EEEEE CCCC A A T EEEEE %
11 % %
12 % %
13 % MagickCore Deprecated Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % October 2002 %
18 % %
19 % %
20 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % https://imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39
40 /*
41 Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
45 # if defined(__CYGWIN__)
46 # include <windows.h>
47 # else
48 /* All MinGW needs ... */
49 # include "MagickCore/nt-base-private.h"
50 # include <wingdi.h>
51 # endif
52 #endif
53 #include "MagickCore/property.h"
54 #include "MagickCore/blob.h"
55 #include "MagickCore/blob-private.h"
56 #include "MagickCore/cache.h"
57 #include "MagickCore/cache-view.h"
58 #include "MagickCore/client.h"
59 #include "MagickCore/color.h"
60 #include "MagickCore/color-private.h"
61 #include "MagickCore/colormap.h"
62 #include "MagickCore/colormap-private.h"
63 #include "MagickCore/colorspace.h"
64 #include "MagickCore/colorspace-private.h"
65 #include "MagickCore/composite.h"
66 #include "MagickCore/composite-private.h"
67 #include "MagickCore/constitute.h"
68 #include "MagickCore/draw.h"
69 #include "MagickCore/draw-private.h"
70 #include "MagickCore/effect.h"
71 #include "MagickCore/enhance.h"
72 #include "MagickCore/exception.h"
73 #include "MagickCore/exception-private.h"
74 #include "MagickCore/fx.h"
75 #include "MagickCore/geometry.h"
76 #include "MagickCore/identify.h"
77 #include "MagickCore/image.h"
78 #include "MagickCore/image-private.h"
79 #include "MagickCore/list.h"
80 #include "MagickCore/log.h"
81 #include "MagickCore/memory_.h"
82 #include "MagickCore/magick.h"
83 #include "MagickCore/monitor.h"
84 #include "MagickCore/monitor-private.h"
85 #include "MagickCore/morphology.h"
86 #include "MagickCore/nt-feature.h"
87 #include "MagickCore/paint.h"
88 #include "MagickCore/pixel.h"
89 #include "MagickCore/pixel-accessor.h"
90 #include "MagickCore/quantize.h"
91 #include "MagickCore/random_.h"
92 #include "MagickCore/resource_.h"
93 #include "MagickCore/semaphore.h"
94 #include "MagickCore/segment.h"
95 #include "MagickCore/splay-tree.h"
96 #include "MagickCore/statistic.h"
97 #include "MagickCore/string_.h"
98 #include "MagickCore/threshold.h"
99 #include "MagickCore/transform.h"
100 #include "MagickCore/utility.h"
101
102 #if !defined(MAGICKCORE_EXCLUDE_DEPRECATED)
103
104 /*
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 % %
107 % %
108 % %
109 + G e t M a g i c k S e e k a b l e S t r e a m %
110 % %
111 % %
112 % %
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 %
115 % GetMagickSeekableStream() returns MagickTrue if the magick supports a
116 % seekable stream.
117 %
118 % The format of the GetMagickSeekableStream method is:
119 %
120 % MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
121 %
122 % A description of each parameter follows:
123 %
124 % o magick_info: The magick info.
125 %
126 */
GetMagickSeekableStream(const MagickInfo * magick_info)127 MagickExport MagickBooleanType GetMagickSeekableStream(
128 const MagickInfo *magick_info)
129 {
130 assert(magick_info != (MagickInfo *) NULL);
131 assert(magick_info->signature == MagickCoreSignature);
132 return(((magick_info->flags & CoderSeekableStreamFlag) == 0) ? MagickFalse :
133 MagickTrue);
134 }
135
136 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
137 /*
138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 % %
140 % %
141 % %
142 % C r o p I m a g e T o H B i t m a p %
143 % %
144 % %
145 % %
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147 %
148 % CropImageToHBITMAP() extracts a specified region of the image and returns
149 % it as a Windows HBITMAP. While the same functionality can be accomplished by
150 % invoking CropImage() followed by ImageToHBITMAP(), this method is more
151 % efficient since it copies pixels directly to the HBITMAP.
152 %
153 % The format of the CropImageToHBITMAP method is:
154 %
155 % HBITMAP CropImageToHBITMAP(Image* image,const RectangleInfo *geometry,
156 % ExceptionInfo *exception)
157 %
158 % A description of each parameter follows:
159 %
160 % o image: the image.
161 %
162 % o geometry: Define the region of the image to crop with members
163 % x, y, width, and height.
164 %
165 % o exception: return any errors or warnings in this structure.
166 %
167 */
CropImageToHBITMAP(Image * image,const RectangleInfo * geometry,ExceptionInfo * exception)168 MagickExport void *CropImageToHBITMAP(Image *image,
169 const RectangleInfo *geometry,ExceptionInfo *exception)
170 {
171 #define CropImageTag "Crop/Image"
172
173 BITMAP
174 bitmap;
175
176 HBITMAP
177 bitmapH;
178
179 HANDLE
180 bitmap_bitsH;
181
182 MagickBooleanType
183 proceed;
184
185 RectangleInfo
186 page;
187
188 const Quantum
189 *p;
190
191 RGBQUAD
192 *q;
193
194 RGBQUAD
195 *bitmap_bits;
196
197 ssize_t
198 y;
199
200 /*
201 Check crop geometry.
202 */
203 assert(image != (const Image *) NULL);
204 assert(image->signature == MagickCoreSignature);
205 if (image->debug != MagickFalse)
206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
207 assert(geometry != (const RectangleInfo *) NULL);
208 assert(exception != (ExceptionInfo *) NULL);
209 assert(exception->signature == MagickCoreSignature);
210 if (((geometry->x+(ssize_t) geometry->width) < 0) ||
211 ((geometry->y+(ssize_t) geometry->height) < 0) ||
212 (geometry->x >= (ssize_t) image->columns) ||
213 (geometry->y >= (ssize_t) image->rows))
214 ThrowImageException(OptionError,"GeometryDoesNotContainImage");
215 page=(*geometry);
216 if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
217 page.width=image->columns-page.x;
218 if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
219 page.height=image->rows-page.y;
220 if (page.x < 0)
221 {
222 page.width+=page.x;
223 page.x=0;
224 }
225 if (page.y < 0)
226 {
227 page.height+=page.y;
228 page.y=0;
229 }
230
231 if ((page.width == 0) || (page.height == 0))
232 ThrowImageException(OptionError,"GeometryDimensionsAreZero");
233 /*
234 Initialize crop image attributes.
235 */
236 bitmap.bmType = 0;
237 bitmap.bmWidth = (LONG) page.width;
238 bitmap.bmHeight = (LONG) page.height;
239 bitmap.bmWidthBytes = bitmap.bmWidth * 4;
240 bitmap.bmPlanes = 1;
241 bitmap.bmBitsPixel = 32;
242 bitmap.bmBits = NULL;
243
244 bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,page.width*
245 page.height*bitmap.bmBitsPixel);
246 if (bitmap_bitsH == NULL)
247 return(NULL);
248 bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
249 if ( bitmap.bmBits == NULL )
250 bitmap.bmBits = bitmap_bits;
251 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
252 SetImageColorspace(image,sRGBColorspace,exception);
253 /*
254 Extract crop image.
255 */
256 q=bitmap_bits;
257 for (y=0; y < (ssize_t) page.height; y++)
258 {
259 ssize_t
260 x;
261
262 p=GetVirtualPixels(image,page.x,page.y+y,page.width,1,exception);
263 if (p == (const Quantum *) NULL)
264 break;
265
266 /* Transfer pixels, scaling to Quantum */
267 for( x=(ssize_t) page.width ; x> 0 ; x-- )
268 {
269 q->rgbRed = ScaleQuantumToChar(GetPixelRed(image,p));
270 q->rgbGreen = ScaleQuantumToChar(GetPixelGreen(image,p));
271 q->rgbBlue = ScaleQuantumToChar(GetPixelBlue(image,p));
272 q->rgbReserved = 0;
273 p+=GetPixelChannels(image);
274 q++;
275 }
276 proceed=SetImageProgress(image,CropImageTag,y,page.height);
277 if (proceed == MagickFalse)
278 break;
279 }
280 if (y < (ssize_t) page.height)
281 {
282 GlobalUnlock((HGLOBAL) bitmap_bitsH);
283 GlobalFree((HGLOBAL) bitmap_bitsH);
284 return((void *) NULL);
285 }
286 bitmap.bmBits=bitmap_bits;
287 bitmapH=CreateBitmapIndirect(&bitmap);
288 GlobalUnlock((HGLOBAL) bitmap_bitsH);
289 GlobalFree((HGLOBAL) bitmap_bitsH);
290 return((void *) bitmapH);
291 }
292 #endif
293
294 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
295 /*
296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297 % %
298 % %
299 % %
300 % I m a g e T o H B i t m a p %
301 % %
302 % %
303 % %
304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 %
306 % ImageToHBITMAP() creates a Windows HBITMAP from an image.
307 %
308 % The format of the ImageToHBITMAP method is:
309 %
310 % HBITMAP ImageToHBITMAP(Image *image,Exceptioninfo *exception)
311 %
312 % A description of each parameter follows:
313 %
314 % o image: the image to convert.
315 %
316 */
ImageToHBITMAP(Image * image,ExceptionInfo * exception)317 MagickExport void *ImageToHBITMAP(Image *image,ExceptionInfo *exception)
318 {
319 BITMAP
320 bitmap;
321
322 HANDLE
323 bitmap_bitsH;
324
325 HBITMAP
326 bitmapH;
327
328 ssize_t
329 x;
330
331 const Quantum
332 *p;
333
334 RGBQUAD
335 *q;
336
337 RGBQUAD
338 *bitmap_bits;
339
340 size_t
341 length;
342
343 ssize_t
344 y;
345
346 (void) memset(&bitmap,0,sizeof(bitmap));
347 bitmap.bmType=0;
348 bitmap.bmWidth=(LONG) image->columns;
349 bitmap.bmHeight=(LONG) image->rows;
350 bitmap.bmWidthBytes=4*bitmap.bmWidth;
351 bitmap.bmPlanes=1;
352 bitmap.bmBitsPixel=32;
353 bitmap.bmBits=NULL;
354 length=bitmap.bmWidthBytes*bitmap.bmHeight;
355 bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,length);
356 if (bitmap_bitsH == NULL)
357 {
358 char
359 *message;
360
361 message=GetExceptionMessage(errno);
362 (void) ThrowMagickException(exception,GetMagickModule(),
363 ResourceLimitError,"MemoryAllocationFailed","`%s'",message);
364 message=DestroyString(message);
365 return(NULL);
366 }
367 bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
368 q=bitmap_bits;
369 if (bitmap.bmBits == NULL)
370 bitmap.bmBits=bitmap_bits;
371 (void) SetImageColorspace(image,sRGBColorspace,exception);
372 for (y=0; y < (ssize_t) image->rows; y++)
373 {
374 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
375 if (p == (const Quantum *) NULL)
376 break;
377 for (x=0; x < (ssize_t) image->columns; x++)
378 {
379 q->rgbRed=ScaleQuantumToChar(GetPixelRed(image,p));
380 q->rgbGreen=ScaleQuantumToChar(GetPixelGreen(image,p));
381 q->rgbBlue=ScaleQuantumToChar(GetPixelBlue(image,p));
382 q->rgbReserved=0;
383 p+=GetPixelChannels(image);
384 q++;
385 }
386 }
387 bitmap.bmBits=bitmap_bits;
388 bitmapH=CreateBitmapIndirect(&bitmap);
389 if (bitmapH == NULL)
390 {
391 char
392 *message;
393
394 message=GetExceptionMessage(errno);
395 (void) ThrowMagickException(exception,GetMagickModule(),
396 ResourceLimitError,"MemoryAllocationFailed","`%s'",message);
397 message=DestroyString(message);
398 }
399 GlobalUnlock((HGLOBAL) bitmap_bitsH);
400 GlobalFree((HGLOBAL) bitmap_bitsH);
401 return((void *) bitmapH);
402 }
403 #endif
404
405 #endif
406