]> git.saurik.com Git - wxWidgets.git/blob - src/common/image.cpp
minor changes for windows compilability
[wxWidgets.git] / src / common / image.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: image.cpp
3 // Purpose: wxImage
4 // Author: Robert Roebling
5 // RCS-ID: $Id$
6 // Copyright: (c) Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "image.h"
12 #endif
13
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #include "wx/image.h"
22 #include "wx/debug.h"
23 #include "wx/log.h"
24 #include "../png/png.h"
25
26 //-----------------------------------------------------------------------------
27 // wxImage
28 //-----------------------------------------------------------------------------
29
30 class wxImageRefData: public wxObjectRefData
31 {
32 public:
33
34 wxImageRefData(void);
35 ~wxImageRefData(void);
36
37 int m_width;
38 int m_height;
39 unsigned char *m_data;
40 bool m_hasMask;
41 unsigned char m_maskRed,m_maskGreen,m_maskBlue;
42 bool m_ok;
43 };
44
45 wxImageRefData::wxImageRefData(void)
46 {
47 m_width = 0;
48 m_height = 0;
49 m_data = (unsigned char*) NULL;
50 m_ok = FALSE;
51 m_maskRed = 0;
52 m_maskGreen = 0;
53 m_maskBlue = 0;
54 m_hasMask = FALSE;
55 }
56
57 wxImageRefData::~wxImageRefData(void)
58 {
59 if (m_data) free( m_data );
60 }
61
62 wxList wxImage::sm_handlers;
63
64 //-----------------------------------------------------------------------------
65
66 #define M_IMGDATA ((wxImageRefData *)m_refData)
67
68 #if !USE_SHARED_LIBRARIES
69 IMPLEMENT_DYNAMIC_CLASS(wxImage, wxObject)
70 #endif
71
72 wxImage::wxImage()
73 {
74 }
75
76 wxImage::wxImage( int width, int height )
77 {
78 Create( width, height );
79 }
80
81 wxImage::wxImage( const wxString& name, long type )
82 {
83 LoadFile( name, type );
84 }
85
86 wxImage::wxImage( const wxImage& image )
87 {
88 Ref(image);
89 }
90
91 wxImage::wxImage( const wxImage* image )
92 {
93 if (image) Ref(*image);
94 }
95
96 void wxImage::Create( int width, int height )
97 {
98 m_refData = new wxImageRefData();
99
100 M_IMGDATA->m_data = (unsigned char *) malloc( width*height*3 );
101 if (M_IMGDATA->m_data)
102 {
103 for (int l = 0; l < width*height*3; l++) M_IMGDATA->m_data[l] = 0;
104
105 M_IMGDATA->m_width = width;
106 M_IMGDATA->m_height = height;
107 M_IMGDATA->m_ok = TRUE;
108 }
109 else
110 {
111 UnRef();
112 }
113 }
114
115 void wxImage::Destroy()
116 {
117 UnRef();
118 }
119
120 bool wxImage::Ok() const
121 {
122 return (M_IMGDATA && M_IMGDATA->m_ok);
123 }
124
125 char unsigned *wxImage::GetData() const
126 {
127 if (!Ok()) return (char unsigned *)NULL;
128
129 return M_IMGDATA->m_data;
130 }
131
132 void wxImage::SetData( char unsigned *WXUNUSED(data) )
133 {
134 }
135
136 void wxImage::SetMaskColour( unsigned char r, unsigned char g, unsigned char b )
137 {
138 if (!Ok()) return;
139
140 M_IMGDATA->m_maskRed = r;
141 M_IMGDATA->m_maskGreen = g;
142 M_IMGDATA->m_maskBlue = b;
143 M_IMGDATA->m_hasMask = TRUE;
144 }
145
146 unsigned char wxImage::GetMaskRed() const
147 {
148 if (!Ok()) return 0;
149
150 return M_IMGDATA->m_maskRed;
151 }
152
153 unsigned char wxImage::GetMaskGreen() const
154 {
155 if (!Ok()) return 0;
156
157 return M_IMGDATA->m_maskGreen;
158 }
159
160 unsigned char wxImage::GetMaskBlue() const
161 {
162 if (!Ok()) return 0;
163
164 return M_IMGDATA->m_maskBlue;
165 }
166
167 void wxImage::SetMask( bool mask )
168 {
169 if (!Ok()) return;
170
171 M_IMGDATA->m_hasMask = mask;
172 }
173
174 bool wxImage::HasMask() const
175 {
176 if (!Ok()) return FALSE;
177
178 return M_IMGDATA->m_hasMask;
179 }
180
181 int wxImage::GetWidth() const
182 {
183 return (M_IMGDATA ? M_IMGDATA->m_width : 0);
184 }
185
186 int wxImage::GetHeight() const
187 {
188 return (M_IMGDATA ? M_IMGDATA->m_height : 0);
189 }
190
191 bool wxImage::LoadFile( const wxString& filename, long type )
192 {
193 UnRef();
194
195 m_refData = new wxImageRefData;
196
197 wxImageHandler *handler = FindHandler(type);
198
199 if (handler == NULL)
200 {
201 wxLogWarning( "No image handler for type %d defined.", type );
202
203 return FALSE;
204 }
205
206 return handler->LoadFile( this, filename );
207 }
208
209 bool wxImage::SaveFile( const wxString& filename, int type )
210 {
211 wxImageHandler *handler = FindHandler(type);
212
213 if (handler == NULL)
214 {
215 wxLogWarning( "No image handler for type %d defined.", type );
216
217 return FALSE;
218 }
219
220 return handler->SaveFile( this, filename );
221 }
222
223 void wxImage::AddHandler( wxImageHandler *handler )
224 {
225 sm_handlers.Append( handler );
226 }
227
228 void wxImage::InsertHandler( wxImageHandler *handler )
229 {
230 sm_handlers.Insert( handler );
231 }
232
233 bool wxImage::RemoveHandler( const wxString& name )
234 {
235 wxImageHandler *handler = FindHandler(name);
236 if (handler)
237 {
238 sm_handlers.DeleteObject(handler);
239 return TRUE;
240 }
241 else
242 return FALSE;
243 }
244
245 wxImageHandler *wxImage::FindHandler( const wxString& name )
246 {
247 wxNode *node = sm_handlers.First();
248 while (node)
249 {
250 wxImageHandler *handler = (wxImageHandler*)node->Data();
251 if (handler->GetName() == name) return handler;
252 node = node->Next();
253 }
254 return (wxImageHandler *)NULL;
255 }
256
257 wxImageHandler *wxImage::FindHandler( const wxString& extension, long bitmapType )
258 {
259 wxNode *node = sm_handlers.First();
260 while (node)
261 {
262 wxImageHandler *handler = (wxImageHandler*)node->Data();
263 if ( handler->GetExtension() == extension &&
264 (bitmapType == -1 || handler->GetType() == bitmapType) )
265 return handler;
266 node = node->Next();
267 }
268 return (wxImageHandler*)NULL;
269 }
270
271 wxImageHandler *wxImage::FindHandler( long bitmapType )
272 {
273 wxNode *node = sm_handlers.First();
274 while (node)
275 {
276 wxImageHandler *handler = (wxImageHandler *)node->Data();
277 if (handler->GetType() == bitmapType) return handler;
278 node = node->Next();
279 }
280 return NULL;
281 }
282
283 void wxImage::CleanUpHandlers()
284 {
285 wxNode *node = sm_handlers.First();
286 while (node)
287 {
288 wxImageHandler *handler = (wxImageHandler *)node->Data();
289 wxNode *next = node->Next();
290 delete handler;
291 delete node;
292 node = next;
293 }
294 }
295
296 //-----------------------------------------------------------------------------
297 // wxImageHandler
298 //-----------------------------------------------------------------------------
299
300 #if !USE_SHARED_LIBRARIES
301 IMPLEMENT_DYNAMIC_CLASS(wxImageHandler,wxObject)
302 #endif
303
304 bool wxImageHandler::LoadFile( wxImage *WXUNUSED(image), const wxString& WXUNUSED(name) )
305 {
306 return FALSE;
307 }
308
309 bool wxImageHandler::SaveFile( wxImage *WXUNUSED(image), const wxString& WXUNUSED(name) )
310 {
311 return FALSE;
312 }
313
314 //-----------------------------------------------------------------------------
315 // wxPNGHandler
316 //-----------------------------------------------------------------------------
317
318 #if !USE_SHARED_LIBRARIES
319 IMPLEMENT_DYNAMIC_CLASS(wxPNGHandler,wxImageHandler)
320 #endif
321
322 bool wxPNGHandler::LoadFile( wxImage *image, const wxString& name )
323 {
324 FILE *f;
325 png_structp png_ptr;
326 png_infop info_ptr;
327 unsigned char *ptr, **lines, *ptr2;
328 int transp,bit_depth,color_type,interlace_type;
329 png_uint_32 width, height;
330 unsigned int i;
331
332 image->Destroy();
333
334 transp = 0;
335 png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
336 if (!png_ptr) return FALSE;
337
338 info_ptr = png_create_info_struct( png_ptr );
339 if (!info_ptr)
340 {
341 png_destroy_read_struct( &png_ptr, NULL, NULL );
342 return FALSE;
343 }
344
345 if (setjmp(png_ptr->jmpbuf))
346 {
347 png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
348 return FALSE;
349 }
350
351 if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
352 {
353 png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
354 return FALSE;
355 }
356
357 f = fopen( name, "rb" );
358 png_init_io( png_ptr, f );
359
360 png_read_info( png_ptr, info_ptr );
361 png_get_IHDR( png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL );
362
363 if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand( png_ptr );
364
365 png_set_strip_16( png_ptr );
366 png_set_packing( png_ptr );
367 if (png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand( png_ptr );
368 png_set_filler( png_ptr, 0xff, PNG_FILLER_AFTER );
369
370 image->Create( width, height );
371
372 if (!image->Ok())
373 {
374 png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
375 return FALSE;
376 }
377
378 lines = (unsigned char **)malloc( height * sizeof(unsigned char *) );
379 if (lines == NULL)
380 {
381 image->Destroy();
382 png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
383 return FALSE;
384 }
385
386 for (i = 0; i < height; i++)
387 {
388 if ((lines[i] = (unsigned char *)malloc(width * (sizeof(unsigned char) * 4))) == NULL)
389 {
390 image->Destroy();
391 for (unsigned int n = 0; n < i; n++) free( lines[n] );
392 free( lines );
393 png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
394 return FALSE;
395 }
396 }
397
398 png_read_image( png_ptr, lines );
399 png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
400 ptr = image->GetData();
401 if ((color_type == PNG_COLOR_TYPE_GRAY) ||
402 (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
403 {
404 for (unsigned int y = 0; y < height; y++)
405 {
406 ptr2 = lines[y];
407 for (unsigned int x = 0; x < width; x++)
408 {
409 unsigned char r = *ptr2++;
410 unsigned char a = *ptr2++;
411 if (a < 128)
412 {
413 *ptr++ = 255;
414 *ptr++ = 0;
415 *ptr++ = 255;
416 transp = 1;
417 }
418 else
419 {
420 *ptr++ = r;
421 *ptr++ = r;
422 *ptr++ = r;
423 }
424 }
425 }
426 }
427 else
428 {
429 for (unsigned int y = 0; y < height; y++)
430 {
431 ptr2 = lines[y];
432 for (unsigned int x = 0; x < width; x++)
433 {
434 unsigned char r = *ptr2++;
435 unsigned char g = *ptr2++;
436 unsigned char b = *ptr2++;
437 unsigned char a = *ptr2++;
438 if (a < 128)
439 {
440 *ptr++ = 255;
441 *ptr++ = 0;
442 *ptr++ = 255;
443 transp = 1;
444 }
445 else
446 {
447 if ((r == 255) && (g == 0) && (b == 255)) r = 254;
448 *ptr++ = r;
449 *ptr++ = g;
450 *ptr++ = b;
451 }
452 }
453 }
454 }
455 for (i = 0; i < height; i++) free( lines[i] );
456 free( lines );
457 if (transp)
458 image->SetMaskColour( 255, 0, 255 );
459 else
460 image->SetMask( FALSE );
461
462 return TRUE;
463 }
464
465
466 bool wxPNGHandler::SaveFile( wxImage *image, const wxString& name )
467 {
468 FILE *f = fopen( name, "wb" );
469 if (f)
470 {
471 png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
472 if (!png_ptr)
473 {
474 fclose( f );
475 return FALSE;
476 }
477
478 png_infop info_ptr = png_create_info_struct(png_ptr);
479 if (info_ptr == NULL)
480 {
481 fclose(f);
482 png_destroy_write_struct( &png_ptr, (png_infopp)NULL );
483 return FALSE;
484 }
485
486 if (setjmp(png_ptr->jmpbuf))
487 {
488 fclose( f );
489 png_destroy_write_struct( &png_ptr, (png_infopp)NULL );
490 return FALSE;
491 }
492
493 png_init_io( png_ptr, f );
494 png_set_IHDR( png_ptr, info_ptr, image->GetWidth(), image->GetHeight(), 8,
495 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
496 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
497
498 png_color_8 sig_bit;
499 sig_bit.red = 8;
500 sig_bit.green = 8;
501 sig_bit.blue = 8;
502 sig_bit.alpha = 8;
503 png_set_sBIT( png_ptr, info_ptr, &sig_bit );
504 png_write_info( png_ptr, info_ptr );
505 png_set_shift( png_ptr, &sig_bit );
506 png_set_packing( png_ptr );
507
508 unsigned char *data = (unsigned char *)malloc( image->GetWidth()*4 );
509 if (!data)
510 {
511 fclose( f );
512 png_destroy_write_struct( &png_ptr, (png_infopp)NULL );
513 return FALSE;
514 }
515
516 for (int y = 0; y < image->GetHeight(); y++)
517 {
518 unsigned char *ptr = image->GetData() + (y * image->GetWidth() * 3);
519 for (int x = 0; x < image->GetWidth(); x++)
520 {
521 data[(x << 2) + 0] = *ptr++;
522 data[(x << 2) + 1] = *ptr++;
523 data[(x << 2) + 2] = *ptr++;
524 if ((data[(x << 2) + 0] == image->GetMaskRed()) &&
525 (data[(x << 2) + 1] == image->GetMaskGreen()) &&
526 (data[(x << 2) + 2] == image->GetMaskBlue()))
527 data[(x << 2) + 3] = 0;
528 else
529 data[(x << 2) + 3] = 255;
530 }
531 png_bytep row_ptr = data;
532 png_write_rows( png_ptr, &row_ptr, 1 );
533 }
534 free(data);
535 png_write_end( png_ptr, info_ptr );
536 png_destroy_write_struct( &png_ptr, (png_infopp)NULL );
537
538 fclose(f);
539 }
540 return TRUE;
541 }
542
543 //-----------------------------------------------------------------------------
544 // wxBMPHandler
545 //-----------------------------------------------------------------------------
546
547 #if !USE_SHARED_LIBRARIES
548 IMPLEMENT_DYNAMIC_CLASS(wxBMPHandler,wxImageHandler)
549 #endif
550
551 bool wxBMPHandler::LoadFile( wxImage *image, const wxString& name )
552 {
553 FILE *file;
554 unsigned char *data, *ptr;
555 int done, i, bpp, planes, comp, ncolors, line, column,
556 linesize, linepos, rshift = 0, gshift = 0, bshift = 0;
557 unsigned char byte;
558 short int word;
559 long int dbuf[4], dword, rmask = 0, gmask = 0, bmask = 0, offset,
560 size;
561 signed char bbuf[4];
562 struct _cmap
563 {
564 unsigned char r, g, b;
565 }
566 *cmap = NULL;
567 #ifndef BI_RGB
568 #define BI_RGB 0
569 #define BI_RLE8 1
570 #define BI_RLE4 2
571 #define BI_BITFIELDS 3
572 #endif
573
574 image->Destroy();
575
576 file = fopen(name, "r");
577 if (!file)
578 return NULL;
579
580 done = 0;
581 /*
582 * Reading the bmp header
583 */
584
585 fread(&bbuf, 1, 2, file);
586
587 fread(dbuf, 4, 4, file);
588
589 size = dbuf[0];
590 offset = dbuf[2];
591
592 fread(dbuf, 4, 2, file);
593 int width = (int)dbuf[0];
594 int height = (int)dbuf[1];
595 if (width > 32767)
596 {
597 fprintf(stderr, "IMLIB ERROR: Image width > 32767 pixels for file\n");
598 fclose(file);
599 return FALSE;
600 }
601 if (height > 32767)
602 {
603 fprintf(stderr, "IMLIB ERROR: Image height > 32767 pixels for file\n");
604 fclose(file);
605 return FALSE;
606 }
607 fread(&word, 2, 1, file);
608 planes = (int)word;
609 fread(&word, 2, 1, file);
610 bpp = (int)word;
611 if (bpp != 1 && bpp != 4 && bpp != 8 && bpp && 16 && bpp != 24 && bpp != 32)
612 {
613 fprintf(stderr, "IMLIB ERROR: unknown bitdepth in file\n");
614 fclose(file);
615 return FALSE;
616 }
617 fread(dbuf, 4, 4, file);
618 comp = (int)dbuf[0];
619 if (comp != BI_RGB && comp != BI_RLE4 && comp != BI_RLE8 && comp != BI_BITFIELDS)
620 {
621 fprintf(stderr, "IMLIB ERROR: unknown encoding in Windows BMP file\n");
622 fclose(file);
623 return FALSE;
624 }
625 fread(dbuf, 4, 2, file);
626 ncolors = (int)dbuf[0];
627 if (ncolors == 0)
628 ncolors = 1 << bpp;
629 /* some more sanity checks */
630 if (((comp == BI_RLE4) && (bpp != 4)) || ((comp == BI_RLE8) && (bpp != 8)) || ((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32)))
631 {
632 fprintf(stderr, "IMLIB ERROR: encoding of BMP doesn't match bitdepth\n");
633 fclose(file);
634 return FALSE;
635 }
636 if (bpp < 16)
637 {
638 cmap = (struct _cmap *)malloc(sizeof(struct _cmap) * ncolors);
639
640 if (!cmap)
641 {
642 fprintf(stderr, "IMLIB ERROR: Cannot allocate RAM for color map in BMP file\n");
643 fclose(file);
644 return FALSE;
645 }
646 }
647 else
648 cmap = NULL;
649
650 image->Create( width, height );
651 ptr = image->GetData();
652 if (!ptr)
653 {
654 fprintf(stderr, "IMLIB ERROR: Cannot allocate RAM for RGB data in file\n");
655 fclose(file);
656 if (cmap)
657 free(cmap);
658 return FALSE;
659 }
660
661 /*
662 * Reading the palette, if it exists.
663 */
664 if (bpp < 16 && ncolors != 0)
665 {
666 for (i = 0; i < ncolors; i++)
667 {
668 fread(bbuf, 1, 4, file);
669 cmap[i].b = bbuf[0];
670 cmap[i].g = bbuf[1];
671 cmap[i].r = bbuf[2];
672 }
673 }
674 else if (bpp == 16 || bpp == 32)
675 {
676 if (comp == BI_BITFIELDS)
677 {
678 int bit = 0;
679
680 fread(dbuf, 4, 3, file);
681 bmask = dbuf[0];
682 gmask = dbuf[1];
683 rmask = dbuf[2];
684 /* find shift amount.. ugly, but i can't think of a better way */
685 for (bit = 0; bit < bpp; bit++)
686 {
687 if (bmask & (1 << bit))
688 bshift = bit;
689 if (gmask & (1 << bit))
690 gshift = bit;
691 if (rmask & (1 << bit))
692 rshift = bit;
693 }
694 }
695 else if (bpp == 16)
696 {
697 rmask = 0x7C00;
698 gmask = 0x03E0;
699 bmask = 0x001F;
700 rshift = 10;
701 gshift = 5;
702 bshift = 0;
703 }
704 else if (bpp == 32)
705 {
706 rmask = 0x00FF0000;
707 gmask = 0x0000FF00;
708 bmask = 0x000000FF;
709 rshift = 16;
710 gshift = 8;
711 bshift = 0;
712 }
713 }
714
715 /*
716 * REading the image data
717 */
718 fseek(file, offset, SEEK_SET);
719 data = ptr;
720
721 /* set the whole image to the background color */
722 if (bpp < 16 && (comp == BI_RLE4 || comp == BI_RLE8))
723 {
724 for (i = 0; i < width * height; i++)
725 {
726 *ptr++ = cmap[0].r;
727 *ptr++ = cmap[0].g;
728 *ptr++ = cmap[0].b;
729 }
730 ptr = data;
731 }
732 line = 0;
733 column = 0;
734 #define poffset (line * width * 3 + column * 3)
735
736 /*
737 * BMPs are stored upside down... hmmmmmmmmmm....
738 */
739
740 linesize = ((width * bpp + 31) / 32) * 4;
741 for (line = (height - 1); line >= 0; line--)
742 {
743 linepos = 0;
744 for (column = 0; column < width;)
745 {
746 if (bpp < 16)
747 {
748 int index;
749
750 linepos++;
751 byte = getc(file);
752 if (bpp == 1)
753 {
754 int bit = 0;
755
756 for (bit = 0; bit < 8; bit++)
757 {
758 index = ((byte & (0x80 >> bit)) ? 1 : 0);
759 ptr[poffset] = cmap[index].r;
760 ptr[poffset + 1] = cmap[index].g;
761 ptr[poffset + 2] = cmap[index].b;
762 column++;
763 }
764 }
765 else if (bpp == 4)
766 {
767 if (comp == BI_RLE4)
768 {
769 fprintf(stderr, "can't deal with 4bit encoded yet.\n");
770 image->Destroy();
771 free(cmap);
772 return FALSE;
773 }
774 else
775 {
776 int nibble = 0;
777
778 for (nibble = 0; nibble < 2; nibble++)
779 {
780 index = ((byte & (0xF0 >> nibble * 4)) >> (!nibble * 4));
781 if (index >= 16)
782 index = 15;
783 ptr[poffset] = cmap[index].r;
784 ptr[poffset + 1] = cmap[index].g;
785 ptr[poffset + 2] = cmap[index].b;
786 column++;
787 }
788 }
789 }
790 else if (bpp == 8)
791 {
792 if (comp == BI_RLE8)
793 {
794 unsigned char first;
795
796 first = byte;
797 byte = getc(file);
798 if (first == 0)
799 {
800 if (byte == 0)
801 {
802 /* column = width; */
803 }
804 else if (byte == 1)
805 {
806 column = width;
807 line = -1;
808 }
809 else if (byte == 2)
810 {
811 byte = getc(file);
812 column += byte;
813 linepos = column * bpp / 8;
814 byte = getc(file);
815 line += byte;
816 }
817 else
818 {
819 int absolute = byte;
820
821 for (i = 0; i < absolute; i++)
822 {
823 +linepos++;
824 byte = getc(file);
825 ptr[poffset] = cmap[byte].r;
826 ptr[poffset + 1] = cmap[byte].g;
827 ptr[poffset + 2] = cmap[byte].b;
828 column++;
829 }
830 if (absolute & 0x01)
831 byte = getc(file);
832 }
833 }
834 else
835 {
836 for (i = 0; i < first; i++)
837 {
838 ptr[poffset] = cmap[byte].r;
839 ptr[poffset + 1] = cmap[byte].g;
840 ptr[poffset + 2] = cmap[byte].b;
841 column++;
842 linepos++;
843 }
844 }
845 }
846 else
847 {
848 ptr[poffset] = cmap[byte].r;
849 ptr[poffset + 1] = cmap[byte].g;
850 ptr[poffset + 2] = cmap[byte].b;
851 column++;
852 linepos += size;
853 }
854 }
855 }
856 else if (bpp == 24)
857 {
858 linepos += fread(&bbuf, 1, 3, file);
859 ptr[poffset] = (unsigned char)bbuf[2];
860 ptr[poffset + 1] = (unsigned char)bbuf[1];
861 ptr[poffset + 2] = (unsigned char)bbuf[0];
862 column++;
863 }
864 else if (bpp == 16)
865 {
866 unsigned char temp;
867
868 linepos += fread(&word, 2, 1, file);
869 temp = (word & rmask) >> rshift;
870 ptr[poffset] = temp;
871 temp = (word & gmask) >> gshift;
872 ptr[poffset + 1] = temp;
873 temp = (word & bmask) >> gshift;
874 ptr[poffset + 2] = temp;
875 column++;
876 }
877 else
878 {
879 unsigned char temp;
880
881 linepos += fread(&dword, 4, 1, file);
882 temp = (dword & rmask) >> rshift;
883 ptr[poffset] = temp;
884 temp = (dword & gmask) >> gshift;
885 ptr[poffset + 1] = temp;
886 temp = (dword & bmask) >> bshift;
887 ptr[poffset + 2] = temp;
888 column++;
889 }
890 }
891 while ((linepos < linesize) && (comp != 1) && (comp != 2))
892 {
893 int temp = fread(&byte, 1, 1, file);
894
895 linepos += temp;
896 if (!temp)
897 break;
898 }
899 }
900 if (cmap) free(cmap);
901
902 image->SetMask( FALSE );
903
904 fclose(file);
905 return TRUE;
906 }
907