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