NCBI C Toolkit Cross Reference

C/vibrant/image.c


  1 /*   image.c
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE
  5 *            National Center for Biotechnology Information (NCBI)
  6 *
  7 *  This software/database is a "United States Government Work" under the
  8 *  terms of the United States Copyright Act.  It was written as part of
  9 *  the author's official duties as a United States Government employee and
 10 *  thus cannot be copyrighted.  This software/database is freely available
 11 *  to the public for use. The National Library of Medicine and the U.S.
 12 *  Government do not place any restriction on its use or reproduction.
 13 *  We would, however, appreciate having the NCBI and the author cited in
 14 *  any work or product based on this material
 15 *
 16 *  Although all reasonable efforts have been taken to ensure the accuracy
 17 *  and reliability of the software and data, the NLM and the U.S.
 18 *  Government do not and cannot warrant the performance or results that
 19 *  may be obtained by using this software or data. The NLM and the U.S.
 20 *  Government disclaim all warranties, express or implied, including
 21 *  warranties of performance, merchantability or fitness for any particular
 22 *  purpose.
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name:  image.c
 27 *
 28 * Author:  Alex Smirnov,  Denis Vakatov
 29 *
 30 * $Revision: 6.9 $
 31 *
 32 * File Description:
 33 *       Image(pixmap) processing.
 34 *
 35 * Version Creation Date:   04/03/95
 36 *
 37 * Modifications:  
 38 * --------------------------------------------------------------------------
 39 *
 40 * ==========================================================================
 41 */
 42 
 43 #include <vibtypes.h>
 44 #include <vibprocs.h>
 45 #include <vibincld.h>
 46 #include <math.h>
 47 
 48 #ifdef WIN_MAC
 49 # if !defined(OS_UNIX_DARWIN)
 50 #include "MoreCarbonAccessors.h"
 51 #endif
 52 #endif
 53 
 54 #ifndef _IMAGE_
 55 #include <image.h>
 56 #endif
 57 #ifndef _PDIAGNOS_
 58 #include <pdiagnos.h>
 59 #endif
 60 
 61 #include <gifgen.h>
 62 
 63 /*****************************************************************************
 64 *
 65 *   TYPEDEFS
 66 *
 67 *****************************************************************************/
 68 typedef struct Nlm_pimage {
 69   Nlm_Uint1        red[256];
 70   Nlm_Uint1        green[256];
 71   Nlm_Uint1        blue[256];
 72   Nlm_Int4         imageVer;
 73   Nlm_Int4         imageVerOld;
 74   Nlm_Int4         imageColorVer;
 75   Nlm_Int4         imageColorVerOld;
 76   Nlm_Uint1Ptr     curImagePtr;
 77   Nlm_Handle       image;
 78   Nlm_WindoW       curWin;
 79   Nlm_Uint2        width;
 80   Nlm_Uint2        height;
 81   Nlm_Uint2        totalColors;
 82   Nlm_Uint2        saveColors;
 83   Nlm_Uint2        imageLocked;
 84 #ifdef WIN_MSWIN
 85   HBITMAP     pixMap;
 86   HDC         hMemDC;
 87   BITMAPINFO *bitInfo;
 88 #endif
 89 #ifdef WIN_MOTIF
 90   Nlm_Uint1   altcol[256];
 91   XImage     *imageX11;
 92 #endif
 93 #ifdef WIN_MAC
 94   PixMap     *pixelMap;
 95 #endif
 96 } Nlm_PImage, PNTR Nlm_PImagePtr;
 97 
 98 /*****************************************************************************
 99 *
100 *   GLOBAL VARIABLE
101 *
102 *****************************************************************************/
103 #ifdef WIN_MSWIN
104 extern HDC Nlm_currentHDC;
105 #endif
106 #ifdef WIN_MOTIF
107 extern Display *Nlm_currentXDisplay;
108 extern Window   Nlm_currentXWindow;
109 extern GC       Nlm_currentXGC;
110 #endif
111 #ifdef WIN_MAC
112 extern Nlm_Boolean  Nlm_hasColorQD;
113 #endif
114 
115 /*****************************************************************************
116 *
117 *   STATIC VARIABLE
118 *
119 *****************************************************************************/
120 static Nlm_CharPtr imageClass = "Image";
121 
122 
123 /*****************************************************************************
124 *
125 *   FUNCTIONS
126 *
127 *****************************************************************************/
128 #ifdef WIN_MSWIN
129 static Nlm_CharPtr GetWinErrStr( void )
130 {
131   static Nlm_Char winErrStr[128];
132 
133 #ifdef BORLAND
134   sprintf(winErrStr, "Windows error %d", GetLastError());
135 #else
136   Nlm_StringCpy(winErrStr, "Windows error");
137 #endif
138 
139   return winErrStr;
140 }
141 
142 
143 static void AllocateColorMap(Nlm_PImagePtr image)
144 {
145   register RGBQUAD *rgbq = image->bitInfo->bmiColors;
146   register int i;
147   int          totalColors = (int)image->totalColors;
148 
149   image->bitInfo->bmiHeader.biClrUsed = totalColors;
150   for (i = 0;  i < totalColors;  i++, rgbq++)
151     {
152       rgbq->rgbRed   = image->red  [i];
153       rgbq->rgbGreen = image->green[i];
154       rgbq->rgbBlue  = image->blue [i];
155       rgbq->rgbReserved = 0;
156     }
157 }
158 #endif
159 
160 
161 Nlm_Image Nlm_CreateImage( void )
162 {
163   Nlm_Image im;
164 
165   Nlm_DiagReset ();
166   im = (Nlm_Image)MemNew( sizeof(Nlm_PImage) );
167   if ( !im )
168     Nlm_DiagPutRecord(DA_ERROR, imageClass, "CreateImage",
169                       "Can not allocate memory block");
170   return im;
171 }
172 
173 
174 Nlm_Boolean Nlm_AllocateImage ( Nlm_Image image, Nlm_Uint2Ptr width,
175                                 Nlm_Uint2 height, Nlm_Uint2 saveColors,
176                                 Nlm_Uint2 totalColors )
177 {
178   register Nlm_PImagePtr im;
179   Nlm_Int2               i;
180 #ifdef WIN_MSWIN
181   BITMAPINFOHEADER PNTR bmpHeader;
182   PALETTEENTRY     PNTR lppe;
183 #endif
184 #ifdef WIN_MOTIF
185   XVisualInfo visinfo;
186 #endif
187 #ifdef WIN_MAC
188   CTabHandle   cTable;
189   CTabPtr      cTablePtr;
190   ColorSpecPtr cSpecPtr;
191 #endif
192 
193   Nlm_DiagReset ();
194   im = (Nlm_PImagePtr)image;
195   im->imageVer++;
196 #ifdef WIN_MSWIN
197   *width /= sizeof(LONG);
198   *width *= sizeof(LONG);
199 #endif
200   if ((*width == 0) || (height == 0) || (totalColors < saveColors) ||
201        (totalColors > 256) ) {
202     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
203                         "Invalid image or palette size" );
204     return FALSE;
205   }
206   if ( im->image != NULL ) {
207     if ( im->imageLocked ) HandUnlock ( im->image );
208     HandFree ( im->image );
209     im->imageLocked = 0;
210   }
211   im->image = HandNew(*width * height );
212   if ( im->image == NULL ) {
213     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
214                         "Can not allocate memory block" );
215     return FALSE;
216   }
217 #ifdef WIN_MSWIN
218   if ( im->bitInfo == NULL ){
219     im->bitInfo = (BITMAPINFO*)MemNew ( sizeof(BITMAPINFOHEADER) +
220                                256*sizeof(RGBQUAD) );
221   }
222   if ( im->bitInfo == NULL ) {
223     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
224                         "Can not allocate memory block" );
225     return FALSE;
226   }
227   bmpHeader = &(im->bitInfo->bmiHeader);
228   bmpHeader->biWidth  = *width;
229   bmpHeader->biHeight = height;
230   bmpHeader->biSize = sizeof(BITMAPINFOHEADER);
231   bmpHeader->biCompression = BI_RGB;
232   bmpHeader->biXPelsPerMeter = 2000;
233   bmpHeader->biYPelsPerMeter = 2000;
234   bmpHeader->biClrImportant = 0;
235   bmpHeader->biSizeImage = 0;
236   bmpHeader->biBitCount = 8;
237   bmpHeader->biPlanes = 1;
238   bmpHeader->biClrUsed = 0;
239   lppe = (PALETTEENTRY PNTR)MemNew ( saveColors * sizeof(PALETTEENTRY));
240   if ( lppe == NULL ) {
241     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
242                         "Can not allocate memory block" );
243   }
244   GetSystemPaletteEntries ( Nlm_currentHDC, 0, saveColors, lppe );
245   for ( i=0; i<saveColors; i++ ) {
246     im->red  [i] = lppe[i].peRed;
247     im->green[i] = lppe[i].peGreen;
248     im->blue [i] = lppe[i].peBlue;
249   }
250   MemFree ( lppe );
251 #endif
252 #ifdef WIN_MOTIF
253 #ifdef OS_UNIX_LINUX 
254   if(!Nlm_CheckX(&visinfo))
255 #else /* OS_UNIX_LINUX */
256   if( !(XMatchVisualInfo(Nlm_currentXDisplay,
257                          DefaultScreen(Nlm_currentXDisplay),
258                          8,PseudoColor,&visinfo) ||
259         XMatchVisualInfo(Nlm_currentXDisplay,
260                          DefaultScreen(Nlm_currentXDisplay),
261                          8,GrayScale,&visinfo)) )
262 #endif /* else OS_UNIX_LINUX */      
263       {
264     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
265 "Your X display cannot support 8-bit(256 colors) neither PseudoColor nor GrayScale visual" );
266     return FALSE;
267   }
268   im->curImagePtr = (Nlm_Uint1Ptr)HandLock ( im->image );
269   if ( im->curImagePtr == NULL ){
270     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
271                         "Can not lock memory block" );
272     return FALSE;
273   }
274   HandUnlock ( im->image );
275   if ( im->imageX11 == NULL ){
276     im->imageX11 = XCreateImage(Nlm_currentXDisplay, 
277                                 visinfo.visual, visinfo.depth, ZPixmap, 0,
278                                 (char*)im->curImagePtr,
279                                 *width, height, 8, 0);
280   }
281   if ( im->imageX11 == NULL ){
282     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
283                         "Can not create X11 image" );
284     return FALSE;
285   }
286 #endif
287 #ifdef WIN_MAC
288 #ifndef WIN_MAC_QUARTZ
289   if ( im->pixelMap == NULL ) {
290     im->pixelMap = (PixMap*)MemNew(sizeof(PixMap));
291   }
292   if ( im->pixelMap == NULL ) {
293     Nlm_DiagPutRecord ( DA_ERROR, imageClass, "AllocateImage",
294                         "Can not allocate memory block" );
295     return FALSE;
296   }
297   im->pixelMap->hRes = 72;
298   im->pixelMap->vRes = 72;
299   im->pixelMap->bounds.left = 0;
300   im->pixelMap->bounds.top = 0;
301   im->pixelMap->cmpSize = 8;
302   /* 2001-03-22:  Joshua Juran */
303   /* Evidently these two members don't exist in Carbon.  So don't set them. */
304 #if !TARGET_API_MAC_CARBON
305   im->pixelMap->planeBytes = 0;
306   im->pixelMap->pmReserved = 0;
307 #endif
308   im->pixelMap->pmVersion = 0;
309   im->pixelMap->packType = 0;
310   im->pixelMap->packSize = 0;
311   im->pixelMap->pixelSize = 8;
312   im->pixelMap->pixelType = 0;
313   im->pixelMap->cmpCount = 1;
314   im->pixelMap->rowBytes = *width | 0x8000;
315   im->pixelMap->bounds.right = *width;
316   im->pixelMap->bounds.bottom = height;
317   cTablePtr = NULL;
318   if ( Nlm_hasColorQD ) cTable = GetCTable ( 72 );
319   else cTable = GetCTable ( 40 );
320   if ( cTable != NULL ){
321     HLock ( (Nlm_Handle)cTable );
322     cTablePtr = (CTabPtr)(*((CTabPtr*)cTable));
323   }
324   if ( cTablePtr != NULL ){
325     cSpecPtr = &(cTablePtr->ctTable[0]);
326     for ( i=0; i<(Nlm_Int2)saveColors; i++ ) {
327       im->red[i] = (cSpecPtr->rgb.red >> 8);
328       im->green[i] = (cSpecPtr->rgb.green >> 8);
329       im->blue[i] = (cSpecPtr->rgb.blue >> 8);
330       cSpecPtr++;
331     }
332     HUnlock ((Nlm_Handle)cTable );
333   } else {
334     for ( i=0; i<(Nlm_Int2)saveColors; i++ ) {
335       if ( i & 0x1 ){
336         im->red[i] = im->green[i] = im->blue[i] = 0;
337       } else {
338         im->red[i] = im->green[i] = im->blue[i] = 0xFFFF;
339       }
340     }
341   }
342   if ( cTable != NULL ) DisposeCTable(cTable);
343 #endif
344 #endif
345 
346   for ( i=saveColors; i<256; i++ )
347     im->red[i] = im->green[i] = im->blue[i] = 0;
348   im->totalColors = totalColors;
349   im->saveColors  = saveColors;
350   im->width  = *width;
351   im->height = height;
352   return TRUE;
353 }
354 
355 
356 Nlm_Image Nlm_LoadImageGIF (Nlm_CharPtr fileName)
357 {
358 #if defined(WIN_MOTIF) || defined(WIN_MSWIN) || defined(WIN_MAC)
359   Nlm_PImagePtr nlm_image = NULL;
360   gdImagePtr    gd_image  = NULL;
361   int           convert[256];
362   Nlm_Uint2     width, height;
363   Nlm_Uint2     nColors, saveColors;
364 
365   Nlm_DiagReset();
366 
367   {{ /* Read "gd"-wise image from the GIF metafile */
368     FILE *inp_stream = FileOpen(fileName, "rb");
369     if ( !inp_stream ) {
370       Nlm_DiagPutRecord(DA_ERROR, imageClass, "LoadImageGIF",
371                         "Can't open GIF file for reading");
372       return NULL;
373     }
374 
375     gd_image  = gdImageCreateFromGif( inp_stream );
376     if ( !gd_image ) {
377       Nlm_DiagPutRecord(DA_ERROR, imageClass, "LoadImageGIF",
378                         "Error occurred while reading GIF file");
379       FileClose( inp_stream );
380       return NULL;
381     }
382     FileClose( inp_stream );
383   }}
384 
385   {{ /* Count number of valid colors in the image */
386     int gd_color;
387 
388     nColors = 0;
389     for (gd_color = 0;  gd_color < gdImageColorsTotal(gd_image);  gd_color++)
390       {
391         if ( gdGetImageColor(gd_image, gd_color, NULL, NULL, NULL) )
392           nColors++;
393       }
394   }}
395 
396   {{ /* Create and allocate "Nlm-wise" image */
397     width   = (Nlm_Uint2)gdImageSX( gd_image );
398     height  = (Nlm_Uint2)gdImageSY( gd_image );
399     saveColors = (Nlm_Uint2)(256 - nColors);
400     if (saveColors > 32)
401       saveColors = 32;
402     nlm_image = (Nlm_PImagePtr)Nlm_CreateImage();
403     if ( !AllocateImage((Nlm_Image)nlm_image, &width, height, saveColors,
404                         (Nlm_Uint2)(saveColors + nColors)) )
405     {
406       Nlm_DiagPutRecord(DA_ERROR, imageClass, "LoadImageGIF",
407                         "Cannot allocate image");
408       Nlm_DeleteImage( (Nlm_Image)nlm_image );
409       gdImageDestroy( gd_image );
410       return NULL;
411     }
412   }}
413 
414   {{ /* Copy palette */
415     int color = saveColors;
416     int gd_color;
417     int red, green, blue;
418     for (gd_color = 0;  gd_color < gdImageColorsTotal(gd_image);  gd_color++)
419       {
420 #ifdef _DEBUG
421         convert[gd_color] = -1;
422 #endif
423         if ( gdGetImageColor(gd_image, gd_color, &red, &green, &blue) )
424           {
425             VERIFY ( Nlm_SetColorImage((Nlm_Image)nlm_image, (Nlm_Uint1)color,
426                                        (Nlm_Uint1)red, (Nlm_Uint1)green,
427                                        (Nlm_Uint1)blue) );
428             convert[gd_color] = color++;
429           }
430       }
431     ASSERT ( color == saveColors + nColors );
432   }}
433 
434 
435   {{ /* Copy gdImage to Nlm_Image */
436     Nlm_Uint2 y;
437     Nlm_Uint1Ptr pixmap = Nlm_LockPixMapImage( (Nlm_Image)nlm_image );
438     for (y = 0;  y < nlm_image->height;  y++)
439       {
440 #if   defined(WIN_MOTIF) || defined(WIN_MAC)
441         Nlm_Uint4 y_base = nlm_image->width * y;
442 #elif defined(WIN_MSWIN)
443         Nlm_Uint4 y_base = nlm_image->width * (nlm_image->height - y - 1);
444 #endif
445         Nlm_Uint2 x;
446         for (x = 0;  x < nlm_image->width;  x++)
447           {
448             int color = gdImageGetPixel(gd_image, x, y);
449             ASSERT ( color < gdImageColorsTotal(gd_image) );
450             ASSERT ( convert[color] != -1 );
451             pixmap[y_base + x] = (Nlm_Uint1)convert[color];
452           }
453       }
454     Nlm_UnlockPixMapImage( (Nlm_Image)nlm_image );
455   }}
456 
457   gdImageDestroy( gd_image );
458   return (Nlm_Image)nlm_image;
459 
460 #else
461   Nlm_DiagReset();
462   Nlm_DiagPutRecord(DA_ERROR, imageClass, "LoadImageGIF", "Not implemented");
463   return NULL;
464 #endif
465 }
466 
467 
468 Nlm_Image Nlm_LoadImageBMP(Nlm_CharPtr fileName)
469 {
470   Nlm_DiagReset();
471   Nlm_DiagPutRecord(DA_ERROR, imageClass, "LoadImageBMP", "Not implemented");
472   return FALSE;
473 }
474 
475 
476 Nlm_Boolean Nlm_LoadImageClip(Nlm_Image image)
477 {
478   Nlm_DiagReset();
479   Nlm_DiagPutRecord(DA_ERROR, imageClass, "LoadImageClip", "Not implemented");
480   return FALSE;
481 }
482 
483 
484 Nlm_Boolean Nlm_SaveImageGIF(Nlm_Image image, Nlm_CharPtr fileName)
485 {
486 #if !defined(_OPENGL) && (defined(WIN_MOTIF) || defined(WIN_MSWIN) || defined(WIN_MAC))
487   Nlm_PImagePtr nlm_image = (Nlm_PImagePtr)image;
488   gdImagePtr gd_image;
489   Nlm_Int2 convert[256];
490 
491   Nlm_DiagReset();
492   if ( !nlm_image ) {
493     Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageGIF", "NULL image");
494     return FALSE;
495   }
496 
497   gd_image = gdImageCreate(nlm_image->width, nlm_image->height);
498 
499   {{ /* Set palette */
500     Nlm_Uint2 color;
501     for (color = nlm_image->saveColors;  color < nlm_image->totalColors;
502          color++)
503       {
504         Nlm_Uint1 red=0, green=0, blue=0;
505         Nlm_GetColorImage(image, (Nlm_Uint1)color, &red, &green, &blue);
506         convert[color] = (Nlm_Int2)gdImageColorAllocate(gd_image,
507                                                         red, green, blue);
508         ASSERT ( 0 <= convert[color]  &&  convert[color] < 256 );
509       }
510   }}
511 
512   {{ /* Copy Nlm_Image to gdImage */
513     Nlm_Uint2 y;
514     Nlm_Uint1Ptr pixmap = Nlm_LockPixMapImage( (Nlm_Image)nlm_image );
515     for (y = 0;  y < nlm_image->height;  y++)
516       {
517 #if   defined(WIN_MOTIF) || defined(WIN_MAC)
518         Nlm_Uint4 y_base = nlm_image->width * y;
519 #elif defined(WIN_MSWIN)
520         Nlm_Uint4 y_base = nlm_image->width * (nlm_image->height - y - 1);
521 #endif
522         Nlm_Uint2 x;
523         for (x = 0;  x < nlm_image->width;  x++)
524           {
525             Nlm_Uint1 color = pixmap[y_base + x];
526             gdImageSetPixel(gd_image, x, y, convert[color]);
527           }
528       }
529     Nlm_UnlockPixMapImage( (Nlm_Image)nlm_image );
530   }}
531 
532   {{ /* Write out */
533     FILE *out_stream = FileOpen(fileName, "wb");
534     if (out_stream == NULL)
535       {
536         gdImageDestroy( gd_image );
537         Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageGIF",
538                           "Can't open GIF file for writing");
539         return FALSE;
540       }
541 
542     gdImageGif(gd_image, out_stream);
543     FileClose( out_stream );
544   }}
545 
546   gdImageDestroy( gd_image );
547   return TRUE;
548 
549 #else
550   Nlm_DiagReset();
551   Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageGIF", "Not implemented");
552   return FALSE;
553 #endif
554 }
555 
556 
557 Nlm_Boolean Nlm_SaveImageBMP(Nlm_Image image, Nlm_CharPtr fileName)
558 {
559   Nlm_DiagReset();
560   Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageBMP", "Not implemented");
561   return FALSE;
562 }
563 
564 
565 Nlm_Boolean Nlm_SaveImageClip(Nlm_Image image)
566 {
567   register Nlm_PImagePtr im = (Nlm_PImagePtr)image;
568 #ifdef WIN_MSWIN
569   BITMAPINFO *bInfo;
570   Nlm_Handle  bInfoHND;
571   Nlm_Int4    sizeHead;
572 #endif
573 
574   Nlm_DiagReset();
575   if ( !im->image ) {
576     Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageClip", "Image is empty");
577     return FALSE;
578   }
579 
580 #ifdef WIN_MSWIN
581   if ( !Nlm_LockPixMapImage(image) )
582     return FALSE;
583 
584   sizeHead = sizeof(BITMAPINFOHEADER) + im->totalColors * sizeof(RGBQUAD);
585   bInfoHND = GlobalAlloc ( GMEM_MOVEABLE | GMEM_DDESHARE,
586                            sizeHead + im->width * im->height);
587   if ( bInfoHND == NULL ) {
588       Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageClip",
589                         "Cannot allocate memory" );
590       UnlockPixMapImage( image );
591       return FALSE;
592   }
593   bInfo = (BITMAPINFO*)HandLock( bInfoHND );
594   MemCpy(bInfo, im->bitInfo, sizeHead);
595   MemCpy((Nlm_Uint1Ptr)bInfo + sizeHead, im->curImagePtr,
596          im->width * im->height);
597 
598   if( !OpenClipboard(NULL) ) {
599     Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageClip", GetWinErrStr());
600     GlobalFree( bInfoHND );
601     UnlockPixMapImage( image );
602     return FALSE;
603   }
604   EmptyClipboard();
605   if ( !SetClipboardData(CF_DIB, bInfoHND) ) {
606     Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageClip", GetWinErrStr());
607     GlobalFree( bInfoHND );
608     CloseClipboard();
609     UnlockPixMapImage( image );
610     return FALSE;
611   }
612   CloseClipboard();
613   UnlockPixMapImage( image );
614   return TRUE;
615 
616 #else
617   Nlm_DiagPutRecord(DA_ERROR, imageClass, "SaveImageClip", "Not implemented");
618   return FALSE;
619 #endif
620 }
621 
622 Nlm_Boolean Nlm_PrintImage ( Nlm_Image image )
623 {
624 #ifdef WIN_MSWIN
625   register Nlm_PImagePtr im = (Nlm_PImagePtr)image;
626   PRINTDLG               pd;
627   Nlm_Uint1Ptr           fBuffer;
628   Nlm_Int2               xsize, ysize, xres, yres;
629   Nlm_Int2               dx, dy, caps;
630   DOCINFO                info;
631   RECT                   rect;
632   HDC                    hDC;
633 #endif
634 
635   Nlm_DiagReset();
636 
637 #ifdef WIN_MSWIN
638   memset (&pd, 0, sizeof (PRINTDLG));
639   pd.lStructSize = sizeof (PRINTDLG);
640   pd.hwndOwner = Nlm_currentHWnd;
641   pd.Flags = PD_RETURNDC;
642   if (PrintDlg (&pd) == 0) return FALSE;
643   hDC = pd.hDC;
644   if( !hDC ) return FALSE;
645   caps = GetDeviceCaps( hDC, RASTERCAPS );
646   if( !(caps & RC_STRETCHDIB) ) return FALSE;
647   xres = GetDeviceCaps( hDC, LOGPIXELSX );
648   yres = GetDeviceCaps( hDC, LOGPIXELSY );
649   xsize = GetDeviceCaps( hDC, HORZRES );
650   ysize = GetDeviceCaps( hDC, VERTRES );
651   dx = (Nlm_Int2)(xsize - xres);
652   dy = (Nlm_Int2)(((Nlm_Int4)dx*im->height)/im->width);
653   rect.top = yres;        rect.bottom = rect.top + dy;
654   rect.left = xres>>1;    rect.right = rect.left + dx;
655   Escape( hDC, SET_BOUNDS, sizeof(RECT), (Nlm_CharPtr)&rect, NULL );
656   info.cbSize = sizeof(DOCINFO);
657   info.lpszDocName = "Vibrant";
658   info.lpszOutput = NULL;
659   StartDoc( hDC, &info );
660   StartPage( hDC );
661   fBuffer = Nlm_LockPixMapImage ( image );
662   StretchDIBits( hDC, xres>>1, yres, dx, dy,
663                  0, 0, im->width, im->height,
664                  fBuffer, im->bitInfo, DIB_RGB_COLORS, SRCCOPY );
665   Nlm_UnlockPixMapImage ( image );
666   EndPage( hDC );
667   EndDoc( hDC );
668   DeleteDC( hDC );
669   if (pd.hDevMode != NULL) {
670     GlobalFree (pd.hDevMode);
671   }
672   if (pd.hDevNames != NULL) {
673     GlobalFree (pd.hDevNames);
674   }
675   return TRUE;
676 
677 #else
678   Nlm_DiagPutRecord(DA_ERROR, imageClass, "PrintImage", "Not implemented");
679   return FALSE;
680 #endif
681 }
682 
683 
684 void Nlm_DeleteImage(Nlm_Image image)
685 {
686   register Nlm_PImagePtr im = (Nlm_PImagePtr)image;
687 
688   if ( im->image )
689     {
690       if ( im->imageLocked )
691         HandUnlock( im->image );
692       HandFree( im->image );
693     }
694 
695   if ( im->curWin != NULL )
696     Nlm_SetColorMap(im->curWin, 0, NULL, NULL, NULL);
697 
698 #ifdef WIN_MSWIN
699   if ( im->hMemDC  )  DeleteDC( im->hMemDC );
700   if ( im->pixMap  )  DeleteObject( im->pixMap );
701   if ( im->bitInfo )  MemFree( im->bitInfo );
702 #endif
703 #ifdef WIN_MOTIF
704   if ( im->imageX11 )
705     {
706       im->imageX11->data = NULL;
707       XDestroyImage( im->imageX11 );
708     }
709 #endif
710 #ifdef WIN_MAC
711 #ifndef WIN_MAC_QUARTZ
712   if ( im->pixelMap )
713     {
714       if ( im->pixelMap->pmTable )
715         DisposeCTable( im->pixelMap->pmTable );
716       MemFree( im->pixelMap );
717     }
718 #endif
719 #endif
720 
721   MemFree( im );
722 }
723 
724 
725 Nlm_Boolean Nlm_SetColorImage(Nlm_Image image, Nlm_Uint1 color,
726                               Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue)
727 {
728   register Nlm_PImagePtr im = (Nlm_PImagePtr)image;
729 
730   Nlm_DiagReset();
731   if (color >= im->totalColors) {
732     Nlm_DiagPutRecord(DA_ERROR, imageClass, "SetColorImage",
733                       "Color is out of range");
734     return FALSE;
735   }
736 
737   if (im->red  [color] != red    ||
738       im->green[color] != green  ||
739       im->blue [color] != blue)
740     {
741       im->red  [color] = red;
742       im->green[color] = green;
743       im->blue [color] = blue;
744       im->imageColorVer++;
745     }
746 
747   return TRUE;
748 }
749 
750 
751 Nlm_Boolean Nlm_GetColorImage(Nlm_Image image, Nlm_Uint1 color,
752                               Nlm_Uint1Ptr red, Nlm_Uint1Ptr green,
753                               Nlm_Uint1Ptr blue)
754 {
755   register Nlm_PImagePtr im = (Nlm_PImagePtr)image;
756 
757   Nlm_DiagReset();
758   if (color >= im->totalColors) {
759     Nlm_DiagPutRecord(DA_ERROR, imageClass, "GetColorImage",
760                       "Color is out of range");
761     return FALSE;
762   }
763   if ( red   )  *red   = im->red  [color];
764   if ( green )  *green = im->green[color];
765   if ( blue  )  *blue  = im->blue [color];
766   return TRUE;
767 }
768 
769 
770 Nlm_Uint1Ptr Nlm_LockPixMapImage(Nlm_Image image)
771 {
772   Nlm_PImagePtr im = (Nlm_PImagePtr)image;
773   if ( !im )
774     return NULL;
775 
776   Nlm_DiagReset();
777 
778   if ( im->imageLocked ) {
779     im->imageLocked++;
780     return im->curImagePtr;
781   }
782   im->curImagePtr = (Nlm_Uint1Ptr)HandLock( im->image );
783   if (im->curImagePtr == NULL)
784     Nlm_DiagPutRecord(DA_ERROR, imageClass, "LockPixMapImage",
785                       "Cannot lock memory block");
786   else
787     im->imageLocked = 1;
788 
789   return im->curImagePtr;
790 }
791 
792 
793 void  Nlm_UnlockPixMapImage(Nlm_Image image)
794 {
795   Nlm_PImagePtr im = (Nlm_PImagePtr)image;
796   if ( !im )
797     return;
798 
799   Nlm_DiagReset();
800   switch ( im->imageLocked ){
801     case 0:
802       break;
803     case 1:
804       HandUnlock ( im->image );
805       im->imageLocked = 0;
806       break;
807     default:
808       im->imageLocked--;
809   }
810 }
811 
812 
813 void Nlm_ImageModified(Nlm_Image image)
814 {
815   ((Nlm_PImagePtr)image)->imageVer++;
816 }
817 
818 
819 void Nlm_GetImageSize(Nlm_Image image, Nlm_Uint2Ptr width, Nlm_Uint2Ptr height)
820 {
821   if ( width  )  *width  = ((Nlm_PImagePtr)image)->width;
822   if ( height )  *height = ((Nlm_PImagePtr)image)->height;
823 }
824 
825 
826 Nlm_Boolean Nlm_ImageSetPalette(Nlm_Image image, Nlm_WindoW w)
827 {
828   ((Nlm_PImagePtr)image)->curWin = w;
829   return TRUE;
830 }
831 
832 #ifdef WIN_MOTIF
833 static int ShiftXMask(unsigned long mask, int bitmap_unit)
834 {
835     int low, hi;
836     for(low = 0; low < bitmap_unit; low++) {
837       if((mask >> low) & (unsigned long)1) break;
838     }
839     for (hi = 1; hi < bitmap_unit - low; hi++) {
840         if(!((mask >> hi + low) & (unsigned long)1)) break;
841     }
842     return low - ( 8 - hi);  /* correct for default 8 bit palette */
843 }
844 #endif /* WIN_MOTIF */
845 
846 Nlm_Boolean Nlm_ImageShow(Nlm_Image image, Nlm_PoinT p)
847 {
848   register Nlm_PImagePtr im = (Nlm_PImagePtr)image;
849 #ifdef WIN_MAC
850   Rect         rectSrc;
851   Rect         rectDst;
852   GrafPtr      port;
853   CTabHandle   tabHandle;
854   CTabPtr      tabPtr;
855   Nlm_Int2     i;
856 #endif
857 #ifdef WIN_MOTIF
858   XVisualInfo visinfo;
859 #endif /* WIN_MOTIF */
860 
861 
862   Nlm_DiagReset();
863   if ( !im->image ) {
864     Nlm_DiagPutRecord(DA_ERROR, imageClass, "ImageShow", "Image is empty");
865     return FALSE;
866   }
867 #ifdef WIN_MSWIN
868   if (im->imageColorVer != im->imageColorVerOld)
869     {
870       if ( im->curWin )
871         Nlm_SetColorMap(im->curWin, im->totalColors,
872                         im->red, im->green, im->blue);
873       AllocateColorMap( im );
874       if (im->hMemDC ) {
875         DeleteDC( im->hMemDC );
876         im->hMemDC = NULL;
877       }
878       im->imageColorVerOld = im->imageColorVer;
879       im->imageVer = im->imageVerOld + 1;
880     }
881 
882   if (im->imageVer != im->imageVerOld)
883     {
884       if ( !Nlm_LockPixMapImage(image) )
885         return FALSE;
886       if ( im->pixMap ) {
887         DeleteObject( im->pixMap );
888         im->pixMap = NULL;
889       }
890       im->pixMap = CreateDIBitmap(Nlm_currentHDC,
891                                   (BITMAPINFOHEADER*)im->bitInfo,
892                                   CBM_INIT, im->curImagePtr, im->bitInfo,
893                                   DIB_RGB_COLORS);
894       Nlm_UnlockPixMapImage( image );
895 
896       if ( !im->pixMap ) {
897         Nlm_DiagPutRecord(DA_ERROR, imageClass, "ImageShow",
898                           "Can not create pixmap");
899         return FALSE;
900       }
901 
902       if ( !im->hMemDC )
903         im->hMemDC = CreateCompatibleDC( Nlm_currentHDC );
904       if ( !im->hMemDC ) {
905         Nlm_DiagPutRecord(DA_ERROR, imageClass, "ImageShow",
906                           "Can not create DC");
907         return FALSE;
908       }
909 
910       SelectObject(im->hMemDC, im->pixMap);
911       im->imageVerOld = im->imageVer;
912     }
913 
914   BitBlt(Nlm_currentHDC,
915          p.x, p.y, im->width, im->height, im->hMemDC, 0, 0, SRCCOPY);
916 #endif
917 
918 #ifdef WIN_MOTIF
919   {{
920     if (im->imageColorVer != im->imageColorVerOld)
921       {
922         if (im->curWin != NULL)
923           Nlm_SetColorMap(im->curWin, im->totalColors,
924                           im->red, im->green, im->blue);
925         else
926           {
927             int col;
928             for (col = im->saveColors;  col < (int)im->totalColors;  col++)
929               im->altcol[col] = Nlm_GetColorRGB(im->red  [col],
930                                                 im->green[col],
931                                                 im->blue [col]);
932           }
933         im->imageColorVerOld = im->imageColorVer;
934       }
935 
936     if (im->curWin == NULL)
937       {
938         register int i, im_size = im->width * im->height;
939         register Nlm_Uint1Ptr  altcol = im->altcol;
940         register Nlm_Uint1Ptr  src    = im->curImagePtr;
941         register Nlm_Uint1Ptr  dst    = (Nlm_Uint1Ptr)
942           Nlm_MemGet(im_size, MGET_ERRPOST);
943 
944         im->imageX11->data = (char *)dst;
945         if ( !im->imageX11->data )
946           return FALSE;
947 
948         for (i = 0;  i < im_size;  i++)
949           *dst++ = altcol[*src++];
950       }
951 #ifdef OS_UNIX_LINUX
952       else if (Nlm_CheckX(&visinfo)){
953           Nlm_Int4 im_size, i, xx, yy;
954           Nlm_Uint1Ptr src = im->curImagePtr;
955           unsigned long dst;
956           int red_shift, blue_shift, green_shift;
957           
958           im_size = (im->imageX11->height * im->imageX11->bytes_per_line
959                   + im->imageX11->xoffset * im->imageX11->bitmap_unit/8);
960           
961           red_shift = ShiftXMask(im->imageX11->red_mask,
962                                 im->imageX11->bitmap_unit);
963           green_shift = ShiftXMask(im->imageX11->green_mask,
964                                 im->imageX11->bitmap_unit);
965           blue_shift = ShiftXMask(im->imageX11->blue_mask,
966                                 im->imageX11->bitmap_unit);
967            
968           if((visinfo.class == PseudoColor || visinfo.class == GrayScale)
969                   && visinfo.depth == 16) {
970             im->imageX11->data = (char *) Nlm_MemNew((size_t)im_size);
971             for (xx = 0; xx < im->imageX11->width; xx++) {
972               for( yy = 0;  yy < im->imageX11->height; yy++) {
973                   i = yy * im->imageX11->width + xx;
974                   XPutPixel(im->imageX11, xx, yy, (unsigned long)src[i]);
975               }
976             }
977           }
978           else if(visinfo.class == TrueColor) {
979             im->imageX11->data = (char *) Nlm_MemNew((size_t)im_size);
980             for (xx = 0; xx < im->imageX11->width; xx++) {
981               for( yy = 0;  yy < im->imageX11->height; yy++) {
982                   i = yy * im->imageX11->width + xx;
983                   dst = (((red_shift > 0 ?
984                           (((unsigned long)im->red[src[i]]) << red_shift) :
985                           (((unsigned long)im->red[src[i]])>>-red_shift)) &
986                           im->imageX11->red_mask) |
987                           ((green_shift > 0 ?
988                           (((unsigned long)im->green[src[i]]) << green_shift) :
989                           (((unsigned long)im->green[src[i]])>>-green_shift)) &
990                           im->imageX11->green_mask) |
991                           ((blue_shift > 0 ?
992                           (((unsigned long)im->blue[src[i]]) << blue_shift) :
993                           (((unsigned long)im->blue[src[i]])>>-blue_shift)) &
994                           im->imageX11->blue_mask) );
995                   XPutPixel(im->imageX11, xx, yy, dst);           
996               }
997             }
998           }
999           else if((visinfo.class == PseudoColor || visinfo.class == GrayScale)
1000                   && visinfo.depth == 8) {
1001               dst = dst;  /* placeholder */
1002           }
1003           else {
1004             Nlm_MemFree(im->imageX11->data);
1005             Nlm_DiagPutRecord(DA_ERROR, imageClass, "ImageShow",
1006                           "Can't handle display class");
1007             return FALSE;
1008           }
1009       }
1010       else {
1011           Nlm_DiagPutRecord(DA_ERROR, imageClass, "ImageShow",
1012                           "Not valid display class");
1013           return FALSE;
1014       }
1015 #endif /* OS_UNIX_LINUX */
1016           
1017     XPutImage(Nlm_currentXDisplay, Nlm_currentXWindow,
1018               Nlm_currentXGC, im->imageX11, 0, 0, p.x, p.y,
1019               im->imageX11->width, im->imageX11->height);
1020 
1021     if (im->curWin == NULL)
1022       {
1023         Nlm_MemFree( im->imageX11->data );
1024         im->imageX11->data = (char *)im->curImagePtr;
1025       }
1026 #ifdef OS_UNIX_LINUX
1027       else if (Nlm_CheckX(&visinfo)) {
1028           if(!((visinfo.class == PseudoColor || visinfo.class == GrayScale)
1029                   && visinfo.depth == 8)) {
1030             MemFree(im->imageX11->data);
1031             im->imageX11->data = (char *)im->curImagePtr;
1032         }
1033       }
1034 #endif /* OS_UNIX_LINUX */
1035 
1036     XFlush( Nlm_currentXDisplay );
1037   }}
1038 #endif
1039 
1040 #ifdef WIN_MAC
1041 #ifndef WIN_MAC_QUARTZ
1042   if ( Nlm_LockPixMapImage(image) == NULL ) return FALSE;
1043   if ( im->imageColorVer != im->imageColorVerOld ){
1044     if ( im->curWin != NULL ){
1045       Nlm_SetColorMap ( im->curWin, im->totalColors,
1046                         im->red, im->green, im->blue );
1047     }
1048     tabHandle = im->pixelMap->pmTable;
1049     if ( tabHandle != NULL ) DisposeCTable ( tabHandle );
1050     im->pixelMap->pmTable = tabHandle = GetCTable(72);
1051     HLock ( (Nlm_Handle)tabHandle );
1052     tabPtr = *tabHandle;
1053     for ( i=0; i<(Nlm_Int2)im->totalColors; i++ ){
1054       tabPtr->ctTable[i].rgb.red   = (Nlm_Uint2)im->red  [i] << 8
1055         | (Nlm_Uint2)im->red[i];
1056       tabPtr->ctTable[i].rgb.green = (Nlm_Uint2)im->green[i] << 8
1057         | (Nlm_Uint2)im->green[i];
1058       tabPtr->ctTable[i].rgb.blue  = (Nlm_Uint2)im->blue [i] << 8
1059         | (Nlm_Uint2)im->blue[i];
1060       if (i >= 255) break;
1061     }
1062     tabPtr->ctSeed = GetCTSeed();
1063     HUnlock((Nlm_Handle)tabHandle );
1064     im->imageColorVerOld = im->imageColorVer;
1065   }
1066   im->pixelMap->baseAddr = (Ptr)im->curImagePtr;
1067   rectSrc.top = 0;   rectSrc.bottom = im->height;
1068   rectSrc.left = 0;  rectSrc.right = im->width;
1069   rectDst.top = p.y;   rectDst.bottom = im->height+p.y;
1070   rectDst.left = p.x;  rectDst.right = im->width+p.x;
1071   GetPort (&port);
1072   CopyBits((BitMap*)im->pixelMap,
1073            GetPortBitMapForCopyBits(port),
1074            &rectSrc, &rectDst, srcCopy, NULL);
1075   BackColor(blackColor);
1076   Nlm_UnlockPixMapImage(image);
1077 #endif
1078 #endif
1079 
1080   return TRUE;
1081 }
1082 
1083 
1084 Nlm_Uint1 Nlm_ImageGetBlack(Nlm_Image image)
1085 {
1086   return (Nlm_Uint1)((Nlm_PImagePtr)image)->saveColors;
1087 }
1088 
1089 Nlm_Uint1 Nlm_ImageGetColorOffset(Nlm_Image image)
1090 {
1091   return (Nlm_Uint1)(((Nlm_PImagePtr)image)->saveColors + 1);
1092 }
1093 
1094 Nlm_Uint1 Nlm_ImageGetColorMax(Nlm_Image image)
1095 {
1096   return (Nlm_Uint1)(((Nlm_PImagePtr)image)->totalColors - 1);
1097 }
1098 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.