1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % CCCC L IIIII PPPP BBBB OOO AAA RRRR DDDD % 7 % C L I P P B B O O A A R R D D % 8 % C L I PPP BBBB O O AAAAA RRRR D D % 9 % C L I P B B O O A A R R D D % 10 % CCCC LLLLL IIIII P BBBB OOO A A R R DDDD % 11 % % 12 % % 13 % Read/Write Windows Clipboard. % 14 % % 15 % Software Design % 16 % Leonard Rosenthol % 17 % May 2002 % 18 % % 19 % % 20 % Copyright 1999-2016 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 % http://www.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 /* 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/blob.h" 54 #include "MagickCore/blob-private.h" 55 #include "MagickCore/cache.h" 56 #include "MagickCore/exception.h" 57 #include "MagickCore/exception-private.h" 58 #include "MagickCore/image.h" 59 #include "MagickCore/image-private.h" 60 #include "MagickCore/list.h" 61 #include "MagickCore/magick.h" 62 #include "MagickCore/memory_.h" 63 #include "MagickCore/nt-feature.h" 64 #include "MagickCore/pixel-accessor.h" 65 #include "MagickCore/quantum-private.h" 66 #include "MagickCore/static.h" 67 #include "MagickCore/string_.h" 68 #include "MagickCore/module.h" 69 70 /* 72 Forward declarations. 73 */ 74 #if defined(MAGICKCORE_WINGDI32_DELEGATE) 75 static MagickBooleanType 76 WriteCLIPBOARDImage(const ImageInfo *,Image *,ExceptionInfo *); 77 #endif 78 79 /* 81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 82 % % 83 % % 84 % % 85 % R e a d C L I P B O A R D I m a g e % 86 % % 87 % % 88 % % 89 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 90 % 91 % ReadCLIPBOARDImage() reads an image from the system clipboard and returns 92 % it. It allocates the memory necessary for the new Image structure and 93 % returns a pointer to the new image. 94 % 95 % The format of the ReadCLIPBOARDImage method is: 96 % 97 % Image *ReadCLIPBOARDImage(const ImageInfo *image_info, 98 % ExceptionInfo exception) 99 % 100 % A description of each parameter follows: 101 % 102 % o image_info: the image info. 103 % 104 % o exception: return any errors or warnings in this structure. 105 % 106 */ 107 #if defined(MAGICKCORE_WINGDI32_DELEGATE) 108 static Image *ReadCLIPBOARDImage(const ImageInfo *image_info, 109 ExceptionInfo *exception) 110 { 111 Image 112 *image; 113 114 MagickBooleanType 115 status; 116 117 register ssize_t 118 x; 119 120 register Quantum 121 *q; 122 123 ssize_t 124 y; 125 126 assert(image_info != (const ImageInfo *) NULL); 127 assert(image_info->signature == MagickCoreSignature); 128 if (image_info->debug != MagickFalse) 129 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 130 image_info->filename); 131 assert(exception != (ExceptionInfo *) NULL); 132 assert(exception->signature == MagickCoreSignature); 133 image=AcquireImage(image_info,exception); 134 { 135 HBITMAP 136 bitmapH; 137 138 HPALETTE 139 hPal; 140 141 OpenClipboard(NULL); 142 bitmapH=(HBITMAP) GetClipboardData(CF_BITMAP); 143 hPal=(HPALETTE) GetClipboardData(CF_PALETTE); 144 CloseClipboard(); 145 if ( bitmapH == NULL ) 146 ThrowReaderException(CoderError,"NoBitmapOnClipboard"); 147 { 148 BITMAPINFO 149 DIBinfo; 150 151 BITMAP 152 bitmap; 153 154 HBITMAP 155 hBitmap, 156 hOldBitmap; 157 158 HDC 159 hDC, 160 hMemDC; 161 162 RGBQUAD 163 *pBits, 164 *ppBits; 165 166 /* create an offscreen DC for the source */ 167 hMemDC=CreateCompatibleDC(NULL); 168 hOldBitmap=(HBITMAP) SelectObject(hMemDC,bitmapH); 169 GetObject(bitmapH,sizeof(BITMAP),(LPSTR) &bitmap); 170 if ((image->columns == 0) || (image->rows == 0)) 171 { 172 image->columns=bitmap.bmWidth; 173 image->rows=bitmap.bmHeight; 174 } 175 status=SetImageExtent(image,image->columns,image->rows,exception); 176 if (status == MagickFalse) 177 return(DestroyImageList(image)); 178 /* 179 Initialize the bitmap header info. 180 */ 181 (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO)); 182 DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 183 DIBinfo.bmiHeader.biWidth=(LONG) image->columns; 184 DIBinfo.bmiHeader.biHeight=(-1)*(LONG) image->rows; 185 DIBinfo.bmiHeader.biPlanes=1; 186 DIBinfo.bmiHeader.biBitCount=32; 187 DIBinfo.bmiHeader.biCompression=BI_RGB; 188 hDC=GetDC(NULL); 189 if (hDC == 0) 190 ThrowReaderException(CoderError,"UnableToCreateADC"); 191 hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits, 192 NULL,0); 193 ReleaseDC(NULL,hDC); 194 if (hBitmap == 0) 195 ThrowReaderException(CoderError,"UnableToCreateBitmap"); 196 /* create an offscreen DC */ 197 hDC=CreateCompatibleDC(NULL); 198 if (hDC == 0) 199 { 200 DeleteObject(hBitmap); 201 ThrowReaderException(CoderError,"UnableToCreateADC"); 202 } 203 hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap); 204 if (hOldBitmap == 0) 205 { 206 DeleteDC(hDC); 207 DeleteObject(hBitmap); 208 ThrowReaderException(CoderError,"UnableToCreateBitmap"); 209 } 210 if (hPal != NULL) 211 { 212 /* Kenichi Masuko says this needed */ 213 SelectPalette(hDC, hPal, FALSE); 214 RealizePalette(hDC); 215 } 216 /* bitblt from the memory to the DIB-based one */ 217 BitBlt(hDC,0,0,(int) image->columns,(int) image->rows,hMemDC,0,0,SRCCOPY); 218 /* finally copy the pixels! */ 219 pBits=ppBits; 220 for (y=0; y < (ssize_t) image->rows; y++) 221 { 222 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); 223 if (q == (Quantum *) NULL) 224 break; 225 for (x=0; x < (ssize_t) image->columns; x++) 226 { 227 SetPixelRed(image,ScaleCharToQuantum(pBits->rgbRed),q); 228 SetPixelGreen(image,ScaleCharToQuantum(pBits->rgbGreen),q); 229 SetPixelBlue(image,ScaleCharToQuantum(pBits->rgbBlue),q); 230 SetPixelAlpha(image,OpaqueAlpha,q); 231 pBits++; 232 q+=GetPixelChannels(image); 233 } 234 if (SyncAuthenticPixels(image,exception) == MagickFalse) 235 break; 236 } 237 DeleteDC(hDC); 238 DeleteObject(hBitmap); 239 } 240 } 241 (void) CloseBlob(image); 242 return(GetFirstImageInList(image)); 243 } 244 #endif /* MAGICKCORE_WINGDI32_DELEGATE */ 245 246 /* 248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 249 % % 250 % % 251 % % 252 % R e g i s t e r C L I P B O A R D I m a g e % 253 % % 254 % % 255 % % 256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 257 % 258 % RegisterCLIPBOARDImage() adds attributes for the clipboard "image format" to 259 % the list of supported formats. The attributes include the image format 260 % tag, a method to read and/or write the format, whether the format 261 % supports the saving of more than one frame to the same file or blob, 262 % whether the format supports native in-memory I/O, and a brief 263 % description of the format. 264 % 265 % The format of the RegisterCLIPBOARDImage method is: 266 % 267 % size_t RegisterCLIPBOARDImage(void) 268 % 269 */ 270 ModuleExport size_t RegisterCLIPBOARDImage(void) 271 { 272 MagickInfo 273 *entry; 274 275 entry=AcquireMagickInfo("CLIPBOARD","CLIPBOARD","The system clipboard"); 276 #if defined(MAGICKCORE_WINGDI32_DELEGATE) 277 entry->decoder=(DecodeImageHandler *) ReadCLIPBOARDImage; 278 entry->encoder=(EncodeImageHandler *) WriteCLIPBOARDImage; 279 #endif 280 entry->flags^=CoderAdjoinFlag; 281 entry->format_type=ImplicitFormatType; 282 (void) RegisterMagickInfo(entry); 283 return(MagickImageCoderSignature); 284 } 285 286 /* 288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 289 % % 290 % % 291 % % 292 % U n r e g i s t e r C L I P B O A R D I m a g e % 293 % % 294 % % 295 % % 296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 297 % 298 % UnregisterCLIPBOARDImage() removes format registrations made by the 299 % RGB module from the list of supported formats. 300 % 301 % The format of the UnregisterCLIPBOARDImage method is: 302 % 303 % UnregisterCLIPBOARDImage(void) 304 % 305 */ 306 ModuleExport void UnregisterCLIPBOARDImage(void) 307 { 308 (void) UnregisterMagickInfo("CLIPBOARD"); 309 } 310 311 /* 313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 314 % % 315 % % 316 % % 317 % W r i t e C L I P B O A R D I m a g e % 318 % % 319 % % 320 % % 321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 322 % 323 % WriteCLIPBOARDImage() writes an image to the system clipboard. 324 % 325 % The format of the WriteCLIPBOARDImage method is: 326 % 327 % MagickBooleanType WriteCLIPBOARDImage(const ImageInfo *image_info, 328 % Image *image,ExceptionInfo *exception) 329 % 330 % A description of each parameter follows. 331 % 332 % o image_info: the image info. 333 % 334 % o image: The image. 335 % 336 % o exception: return any errors or warnings in this structure. 337 % 338 */ 339 #if defined(MAGICKCORE_WINGDI32_DELEGATE) 340 static MagickBooleanType WriteCLIPBOARDImage(const ImageInfo *image_info, 341 Image *image,ExceptionInfo *exception) 342 { 343 /* 344 Allocate memory for pixels. 345 */ 346 assert(image_info != (const ImageInfo *) NULL); 347 assert(image_info->signature == MagickCoreSignature); 348 assert(image != (Image *) NULL); 349 assert(image->signature == MagickCoreSignature); 350 if (image->debug != MagickFalse) 351 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 352 { 353 HBITMAP 354 bitmapH; 355 356 OpenClipboard(NULL); 357 EmptyClipboard(); 358 bitmapH=(HBITMAP) ImageToHBITMAP(image,exception); 359 SetClipboardData(CF_BITMAP,bitmapH); 360 CloseClipboard(); 361 } 362 return(MagickTrue); 363 } 364 #endif /* MAGICKCORE_WINGDI32_DELEGATE */ 365