|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/vibrant/image.c |
source navigation diff markup identifier search freetext search file search |
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 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |