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