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