~cosme/ubuntu/precise/freeimage/freeimage-3.15.1

« back to all changes in this revision

Viewing changes to Source/FreeImage/PluginTARGA.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-07-20 13:42:15 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100720134215-xt1454zaedv3b604
Tags: 3.13.1-0ubuntu1
* New upstream release. Closes: (LP: #607800)
 - Updated debian/freeimage-get-orig-source script.
 - Removing no longer necessary debian/patches/* and
   the patch system in debian/rules.
 - Updated debian/rules to work with the new Makefiles.
 - Drop from -O3 to -O2 and use lzma compression saves
   ~10 MB of free space. 
* lintian stuff
 - fixed debhelper-but-no-misc-depends
 - fixed ldconfig-symlink-missing-for-shlib

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
// - Martin Weber (martweb@gmx.net)
8
8
// - Machiel ten Brinke (brinkem@uni-one.nl)
9
9
// - Peter Lemmens (peter.lemmens@planetinternet.be)
10
 
// - Herv� Drolon (drolon@infonie.fr)
 
10
// - Hervé Drolon (drolon@infonie.fr)
 
11
// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
11
12
//
12
13
// This file is part of FreeImage 3
13
14
//
26
27
 
27
28
#include "FreeImage.h"
28
29
#include "Utilities.h"
29
 
 
 
30
 
30
31
// ----------------------------------------------------------
31
32
//   Constants + headers
32
33
// ----------------------------------------------------------
84
85
// Internal functions
85
86
// ==========================================================
86
87
 
 
88
/**
 
89
This struct is used only when loading RLE compressed images.
 
90
It is needed because it is (really) hard to determine the size of a
 
91
compressed line in the file (and allocate line cache as usual, refilling it at line change).
 
92
We use an arbitrary size instead and access it through this struct, it takes care to refill when needed.
 
93
NOTE: access must be *fast*, so safety measures are minimal.
 
94
*/
 
95
typedef struct tagCacheIO {
 
96
    BYTE *ptr;
 
97
        BYTE *home;
 
98
        BYTE *end;
 
99
    size_t size;
 
100
    FreeImageIO *io;    // not necessary, but
 
101
    fi_handle handle;   // passing them as args is slower
 
102
} CacheIO;
 
103
 
 
104
/**
 
105
Returns TRUE on success and FAlSE if malloc fails
 
106
Note however that I do not use this returned value in the code. 
 
107
Allocating line cache even for a 100 000 wide 32bit bitmap will take under
 
108
half a megabyte. Out of Mem is really not an issue!
 
109
*/
 
110
static BOOL
 
111
cacheIO_alloc(CacheIO *ch, FreeImageIO *io, fi_handle handle, size_t size) {
 
112
        ch->home = NULL;
 
113
    ch->home = (BYTE*)malloc(size);
 
114
        if(ch->home == NULL) {
 
115
        return FALSE;
 
116
        }
 
117
    ch->end = ch->home + size;
 
118
    ch->size = size;
 
119
    ch->io = io;
 
120
    ch->handle = handle;
 
121
    ch->ptr = ch->end;  //will force refill on first access
 
122
 
 
123
    return TRUE;
 
124
}
 
125
 
 
126
static void
 
127
cacheIO_free(CacheIO *ch) {
 
128
        if(ch->home != NULL) {
 
129
        free(ch->home);
 
130
        }
 
131
}
 
132
 
 
133
inline static BYTE
 
134
cacheIO_getByte(CacheIO *ch) {
 
135
        if(ch->ptr >= ch->end) {
 
136
                ch->ptr = ch->home;
 
137
                ch->io->read_proc(ch->ptr, sizeof(BYTE), (unsigned)ch->size, ch->handle);//### EOF - no problem?
 
138
        }
 
139
        BYTE result = *ch->ptr;
 
140
        ch->ptr++;
 
141
 
 
142
    return result;
 
143
}
 
144
 
 
145
inline static BYTE*
 
146
cacheIO_getBytes(CacheIO *ch, size_t count /*must be < ch.size!*/) {
 
147
        if(ch->ptr + count >= ch->end) {
 
148
                // 'count' bytes might span two cache bounds, SEEK back to add them in the new cache
 
149
                long read = (long)(ch->ptr - ch->home);
 
150
                ch->io->seek_proc(ch->handle, -(((long)ch->size - read)), SEEK_CUR);
 
151
                ch->ptr = ch->home;
 
152
                ch->io->read_proc(ch->ptr, sizeof(BYTE), (unsigned)ch->size, ch->handle);//### EOF - no problem?
 
153
        }
 
154
        BYTE *result = ch->ptr;
 
155
        ch->ptr += count;
 
156
 
 
157
    return result;
 
158
}
 
159
 
87
160
static BYTE *
88
161
Internal_GetScanLine(FIBITMAP *dib, int scanline, int flipvert) {
89
162
        //assert ((scanline >= 0) && (scanline < (int)FreeImage_GetHeight(dib)));
90
163
 
91
 
        if (flipvert)
 
164
        if (flipvert) {
92
165
                return FreeImage_GetScanLine(dib, scanline);
93
 
        else
 
166
        } else {
94
167
                return FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - scanline - 1);
 
168
        }
95
169
}
96
170
 
97
171
#ifdef FREEIMAGE_BIGENDIAN
165
239
        //   NO, according to http://cvs.sf.net/viewcvs.py/eifogl/eifogl/utility/tga/tga_file.e?rev=1.3
166
240
        //       and it seems that the current Targa implementation for FreeImage
167
241
        //       assumes that anything other than 0 means that there is a Color Map
168
 
        if(header.color_map_type != 0 && header.color_map_type != 1)
 
242
        if(header.color_map_type != 0 && header.color_map_type != 1) {
169
243
                return FALSE;
 
244
        }
170
245
 
171
246
        // If the Color Map Type is 1 then we validate the map entry information...
172
247
        // NOTA: let's stay compatible with the current FreeImage Targa implementation
193
268
        }
194
269
 
195
270
        // the width/height shouldn't be 0, right?
196
 
        if(header.is_width == 0 || header.is_height == 0)
 
271
        if(header.is_width == 0 || header.is_height == 0) {
197
272
                return FALSE;
 
273
        }
198
274
 
199
275
        // the extra data (following after the header) should be there
200
276
        if(io->read_proc(extra, 1, header.id_length, handle) != header.id_length)
203
279
        // let's now verify all the types that are supported by FreeImage
204
280
        // NOTE : this is our final verification
205
281
        switch(header.is_pixel_depth) {
206
 
                case 8: 
 
282
                case 8:
207
283
                        switch(header.image_type) {
208
284
                          case TGA_CMAP:
209
285
                          case TGA_MONO:
214
290
                case 15:
215
291
                case 16:
216
292
                case 24:
217
 
                case 32: 
 
293
                case 32:
218
294
                        switch(header.image_type) {
219
295
                                case TGA_RGB:
220
296
                                case TGA_RLERGB: return TRUE;
234
310
                );
235
311
}
236
312
 
237
 
static BOOL DLL_CALLCONV 
 
313
static BOOL DLL_CALLCONV
238
314
SupportsExportType(FREE_IMAGE_TYPE type) {
239
315
        return (type == FIT_BITMAP) ? TRUE : FALSE;
240
316
}
246
322
        if (handle) {
247
323
                try {
248
324
                        // remember the start offset
249
 
 
250
325
                        long start_offset = io->tell_proc(handle);
251
326
 
 
327
                        // remember end-of-file (used for RLE cache)
 
328
                        io->seek_proc(handle, 0, SEEK_END);
 
329
                        long eof = io->tell_proc(handle);
 
330
                        io->seek_proc(handle, start_offset, SEEK_SET );
 
331
 
252
332
                        // read and process the bitmap's header
253
333
 
254
334
                        FIBITMAP *dib = NULL;
262
342
 
263
343
                        int line = CalculateLine(header.is_width, header.is_pixel_depth);
264
344
                        int pitch = CalculatePitch(line);
 
345
                        // It seems this ALWAYS is: 8 for 32bit, 1 for 16bit, 0 for 24bit
265
346
                        int alphabits = header.is_image_descriptor & 0x0f;
266
347
                        int fliphoriz = (header.is_image_descriptor & 0x10) ? 0 : 1; //currently FreeImage improperly treats this as flipvert also
267
348
                        int flipvert = (header.is_image_descriptor & 0x20) ? 1 : 0;
274
355
                                {
275
356
                                        dib = FreeImage_Allocate(header.is_width, header.is_height, 8);
276
357
 
277
 
                                        if (dib == NULL)
278
 
                                                throw "DIB allocation failed";
279
 
                                        
 
358
                                        if (dib == NULL) {
 
359
                                                throw FI_MSG_ERROR_DIB_MEMORY;
 
360
                                        }
 
361
 
280
362
                                        // read the palette
281
363
 
282
364
                                        RGBQUAD *palette = FreeImage_GetPalette(dib);
304
386
                                                        case 16:
305
387
                                                        {
306
388
                                                                WORD *rgb555 = (WORD*)&cmap[0];
307
 
                                                                for (count = header.cm_first_entry; count < header.cm_length; count++) {                                                
 
389
                                                                for (count = header.cm_first_entry; count < header.cm_length; count++) {
308
390
                                                                        palette[count].rgbRed   = (BYTE)((((*rgb555 & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
309
391
                                                                        palette[count].rgbGreen = (BYTE)((((*rgb555 & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
310
392
                                                                        palette[count].rgbBlue  = (BYTE)((((*rgb555 & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
333
415
                                                                memset(trns, 0xFF, 256);
334
416
 
335
417
                                                                FILE_BGRA *bgra = (FILE_BGRA*)&cmap[0];
336
 
                                                                for (count = header.cm_first_entry; count < header.cm_length; count++) {                                                
337
 
                                                                        palette[count].rgbBlue  = bgra->b;                                                                      
 
418
                                                                for (count = header.cm_first_entry; count < header.cm_length; count++) {
 
419
                                                                        palette[count].rgbBlue  = bgra->b;
338
420
                                                                        palette[count].rgbGreen = bgra->g;
339
421
                                                                        palette[count].rgbRed   = bgra->r;
340
422
                                                                        // alpha
350
432
 
351
433
                                                free(cmap);
352
434
                                        }
353
 
                                        
 
435
 
354
436
                                        // read in the bitmap bits
355
437
 
356
438
                                        switch (header.image_type) {
371
453
                                                                        io->read_proc(bits, sizeof(BYTE), line, handle);
372
454
                                                                }
373
455
                                                        }
374
 
                                                        
 
456
 
375
457
                                                        break;
376
458
                                                }
377
459
 
378
460
                                                case TGA_RLECMAP:
379
 
                                                case TGA_RLEMONO:
 
461
                                                case TGA_RLEMONO: //(8 bit)
380
462
                                                {
381
 
                                                        int x = 0;
382
 
                                                        int y = 0;
383
463
                                                        BYTE rle = 0;
384
464
                                                        BYTE *bits;
385
 
                                                        
386
 
                                                        if (fliphoriz)
 
465
 
 
466
                                                        // Compute the *rough* size of a line...
 
467
                                                        long pixels_offset = io->tell_proc(handle);
 
468
                                                        long sz = ((eof - pixels_offset) / header.is_height);
 
469
 
 
470
                                                        // ...and allocate cache of this size (yields best results)
 
471
                                                        CacheIO cache;
 
472
                                                        cacheIO_alloc(&cache, io, handle, sz);
 
473
 
 
474
                                                        int y = 0, x = 0;
 
475
 
 
476
                                                        if (fliphoriz) {
387
477
                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
388
 
                                                        else
 
478
                                                        } else {
389
479
                                                                bits = Internal_GetScanLine(dib, y, flipvert);
390
 
 
391
 
                                                        while(1) {
392
 
                                                                io->read_proc(&rle,1, 1, handle);
393
 
                                                                
394
 
                                                                if (rle>127) {
395
 
                                                                        rle -= 127;
396
 
 
397
 
                                                                        BYTE triple;
398
 
 
399
 
                                                                        io->read_proc(&triple, 1, 1, handle);
400
 
 
401
 
                                                                        for (int ix = 0; ix < rle; ix++) {
402
 
                                                                                bits[x++] = triple;
403
 
 
404
 
                                                                                if (x >= line) {
405
 
                                                                                        x = 0;
406
 
 
407
 
                                                                                        y++;
408
 
 
409
 
                                                                                        if (y >= header.is_height)
410
 
                                                                                                goto done89;
411
 
                                                                                        
412
 
                                                                                        if (fliphoriz)
413
 
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
414
 
                                                                                        else
415
 
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
416
 
                                                                                }
417
 
                                                                        }
418
 
                                                                } else {
419
 
                                                                        rle++;
420
 
 
421
 
                                                                        for (int ix = 0; ix < rle; ix++) {
422
 
                                                                                BYTE triple;            
423
 
 
424
 
                                                                                io->read_proc(&triple, 1, 1, handle);
425
 
 
426
 
                                                                                bits[x++] = triple;
427
 
                                                                                
428
 
                                                                                if (x >= line) {
429
 
                                                                                        x = 0;
430
 
 
431
 
                                                                                        y++;
432
 
 
433
 
                                                                                        if (y >= header.is_height)
434
 
                                                                                                goto done89;
435
 
                                                                                        
436
 
                                                                                        if (fliphoriz)
437
 
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
438
 
                                                                                        else
439
 
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
440
 
                                                                                }
441
 
                                                                        }
442
 
                                                                }
443
480
                                                        }
444
 
                                        done89 :
 
481
 
 
482
                                                        while(y < header.is_height) {
 
483
 
 
484
                                                                rle = cacheIO_getByte(&cache);
 
485
 
 
486
                                                                BOOL has_rle = rle & 0x80;
 
487
                                                                rle &= ~0x80;   // remove type-bit
 
488
 
 
489
                                                                BYTE rle_count = rle + 1;
 
490
 
 
491
                                                                if (has_rle) {
 
492
 
 
493
                                                                        BYTE val = cacheIO_getByte(&cache);
 
494
 
 
495
                                                                        for(int ix = 0; ix < rle_count; ix++) {
 
496
                                                                                bits[x++] = val;
 
497
 
 
498
                                                                                if(x >= line){
 
499
                                                                                        x = 0;
 
500
                                                                                        y++;
 
501
                                                                                        if (fliphoriz) {
 
502
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
503
                                                                                        } else {
 
504
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
 
505
                                                                                        }
 
506
                                                                                }
 
507
                                                                        }
 
508
 
 
509
                                                                } else { // !has_rle
 
510
 
 
511
                                                                        for(int ix = 0; ix < rle_count; ix++) {
 
512
 
 
513
                                                                                BYTE val = cacheIO_getByte(&cache);
 
514
                                                                                bits[x++] = val;
 
515
                                                                                if(x >= line){
 
516
                                                                                        x=0;
 
517
                                                                                        y++;
 
518
                                                                                        if (fliphoriz) {
 
519
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
520
                                                                                        } else {
 
521
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
 
522
                                                                                        }
 
523
                                                                                }
 
524
                                                                        }//< rle_count
 
525
                                                                }//< has_rle
 
526
                                                        }//< while y
 
527
 
 
528
                                                        cacheIO_free(&cache);
445
529
                                                        break;
446
530
                                                }
447
 
                                                
 
531
 
448
532
                                                default :
449
533
                                                        FreeImage_Unload(dib);
450
534
                                                        return NULL;
462
546
 
463
547
                                        if (TARGA_LOAD_RGB888 & flags) {
464
548
                                                pixel_bits = 24;
465
 
 
466
549
                                                dib = FreeImage_Allocate(header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
467
 
                                        } else {                        
 
550
                                        } else {
468
551
                                                pixel_bits = 16;
469
 
 
470
552
                                                dib = FreeImage_Allocate(header.is_width, header.is_height, pixel_bits, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
471
553
                                        }
472
554
 
473
 
                                        if (dib == NULL)
474
 
                                                throw "DIB allocation failed";
 
555
                                        if (dib == NULL) {
 
556
                                                throw FI_MSG_ERROR_DIB_MEMORY;
 
557
                                        }
475
558
 
476
559
                                        int line = CalculateLine(header.is_width, pixel_bits);
477
560
 
478
561
                                        const unsigned pixel_size = unsigned(pixel_bits) / 8;
479
562
 
480
 
                                        // note header.cm_size is a misleading name, it should be seen as header.cm_bits 
 
563
                                        // note header.cm_size is a misleading name, it should be seen as header.cm_bits
481
564
                                        // ignore current position in file and set filepointer explicitly from the beginning of the file
482
565
 
483
566
                                        int garblen = 0;
484
567
 
485
 
                                        if (header.color_map_type != 0)
 
568
                                        if (header.color_map_type != 0) {
486
569
                                                garblen = (int)((header.cm_size + 7) / 8) * header.cm_length; /* should byte align */
487
 
                                        else
 
570
                                        } else {
488
571
                                                garblen = 0;
 
572
                                        }
489
573
 
490
574
                                        io->seek_proc(handle, start_offset, SEEK_SET);
491
575
                                        io->seek_proc(handle, sizeof(tagTGAHEADER) + header.id_length + garblen, SEEK_SET);
492
576
 
493
577
                                        // read in the bitmap bits
494
578
 
495
 
                                        WORD pixel;
496
 
                                                        
497
579
                                        switch (header.image_type) {
498
 
                                                case TGA_RGB:
499
 
                                                {
500
 
                                                        for (int y = 0; y < header.is_height; y++) {
501
 
                                                                BYTE *bits;
502
 
                                                                
503
 
                                                                if (fliphoriz)
504
 
                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
505
 
                                                                else
506
 
                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
507
 
 
508
 
                                                                for (int x = 0; x < line; ) {
509
 
                                                                        io->read_proc(&pixel, sizeof(WORD), 1, handle);
510
 
#ifdef FREEIMAGE_BIGENDIAN
511
 
                                                                        SwapShort(&pixel);
512
 
#endif
513
 
                                                                
514
 
                                                                        if (TARGA_LOAD_RGB888 & flags) {
515
 
                                                                                bits[x + FI_RGBA_BLUE]  = (BYTE)((((pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
516
 
                                                                                bits[x + FI_RGBA_GREEN] = (BYTE)((((pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
517
 
                                                                                bits[x + FI_RGBA_RED]   = (BYTE)((((pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
518
 
                                                                        } else {
519
 
                                                                                *reinterpret_cast<WORD*>(bits + x) = 0x7FFF & pixel;
 
580
                                        case TGA_RGB: //(16 bit)
 
581
                                        {
 
582
                                                // in(put)_line cache
 
583
                                                WORD *in_line = (WORD*)malloc(header.is_width * sizeof(WORD));
 
584
                                                if(!in_line) throw FI_MSG_ERROR_MEMORY;
 
585
 
 
586
                                                const int h = header.is_height;
 
587
                                                for (int y = 0; y < h; y++) {
 
588
                                                        BYTE *bits;
 
589
 
 
590
                                                        if (fliphoriz) {
 
591
                                                                bits = Internal_GetScanLine(dib, h - y - 1, flipvert);
 
592
                                                        } else {
 
593
                                                                bits = Internal_GetScanLine(dib, y, flipvert);
 
594
                                                        }
 
595
                                                        io->read_proc(in_line, sizeof(WORD), header.is_width, handle);
 
596
 
 
597
                                                        WORD *pixel = in_line;
 
598
                                                        for (int x = 0; x < line; x += pixel_size) {
 
599
 
 
600
#ifdef FREEIMAGE_BIGENDIAN
 
601
                                                                        SwapShort(pixel);
 
602
#endif
 
603
 
 
604
                                                                        if (TARGA_LOAD_RGB888 & flags) {
 
605
                                                                                bits[x + FI_RGBA_BLUE]  = (BYTE)((((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
 
606
                                                                                bits[x + FI_RGBA_GREEN] = (BYTE)((((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
 
607
                                                                                bits[x + FI_RGBA_RED]   = (BYTE)((((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
 
608
                                                                        } else {
 
609
                                                                                *reinterpret_cast<WORD*>(bits + x) = 0x7FFF & *pixel;
 
610
                                                                        }
 
611
                                                                        pixel++;
 
612
                                                        }
 
613
                                                }
 
614
 
 
615
                                                free(in_line);
 
616
                                                break;
 
617
                                        }
 
618
 
 
619
                                        case TGA_RLERGB: //(16 bit)
 
620
                                        {
 
621
                                                BYTE rle;
 
622
                                                BYTE *bits;
 
623
 
 
624
                                                // Compute the *rough* size of a line...
 
625
                                                long pixels_offset = io->tell_proc(handle);
 
626
                                                long sz = ((eof - pixels_offset) / header.is_height);
 
627
 
 
628
                                                // ...and allocate cache of this size (yields best results)
 
629
                                                CacheIO cache;
 
630
                                                cacheIO_alloc(&cache, io, handle, sz);
 
631
 
 
632
                                                int y = 0, x = 0;
 
633
 
 
634
                                                if (fliphoriz) {
 
635
                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
636
                                                } else {
 
637
                                                        bits = Internal_GetScanLine(dib, y, flipvert);
 
638
                                                }
 
639
 
 
640
                                                while( y < header.is_height) {
 
641
                                                        rle = cacheIO_getByte(&cache);
 
642
 
 
643
                                                        BOOL has_rle = rle & 0x80;
 
644
                                                        rle &= ~0x80; //remove type-bit
 
645
 
 
646
                                                        int rle_count = rle + 1;
 
647
 
 
648
                                                        if (has_rle) {
 
649
 
 
650
                                                                WORD *val = (WORD*)cacheIO_getBytes(&cache, sizeof(WORD));
 
651
#ifdef FREEIMAGE_BIGENDIAN
 
652
                                                                SwapShort(val);
 
653
#endif
 
654
                                                                        for (int ix = 0; ix < rle_count; ix++) {
 
655
                                                                                if (TARGA_LOAD_RGB888 & flags) {
 
656
                                                                                        bits[x + FI_RGBA_BLUE]  = (BYTE)((((*val & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
 
657
                                                                                        bits[x + FI_RGBA_GREEN] = (BYTE)((((*val & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
 
658
                                                                                        bits[x + FI_RGBA_RED]   = (BYTE)((((*val & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
 
659
                                                                                } else {
 
660
                                                                                        *reinterpret_cast<WORD *>(bits + x) = 0x7FFF & *val;
 
661
                                                                                }
 
662
 
 
663
                                                                                x += pixel_size;
 
664
 
 
665
                                                                                if(x >= line){
 
666
                                                                                        x = 0;
 
667
                                                                                        y++;
 
668
 
 
669
                                                                                        if (fliphoriz) {
 
670
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
671
                                                                                        } else {
 
672
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
 
673
                                                                                        }
 
674
                                                                                }
 
675
                                                                        }
 
676
 
 
677
                                                        } else {
 
678
 
 
679
                                                                for (int ix = 0; ix < rle_count; ix++) {
 
680
                                                                        WORD *val = (WORD*)cacheIO_getBytes(&cache, sizeof(WORD));
 
681
 
 
682
#ifdef FREEIMAGE_BIGENDIAN
 
683
                                                                        SwapShort(val);
 
684
#endif
 
685
 
 
686
                                                                        if (TARGA_LOAD_RGB888 & flags) {
 
687
                                                                                bits[x + FI_RGBA_BLUE]  = (BYTE)((((*val & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
 
688
                                                                                bits[x + FI_RGBA_GREEN] = (BYTE)((((*val & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
 
689
                                                                                bits[x + FI_RGBA_RED]   = (BYTE)((((*val & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
 
690
                                                                        } else {
 
691
                                                                                *reinterpret_cast<WORD *>(bits + x) = 0x7FFF & *val;
520
692
                                                                        }
521
693
 
522
694
                                                                        x += pixel_size;
523
 
                                                                }
524
 
                                                        }
525
 
 
526
 
                                                        break;
527
 
                                                }
528
 
 
529
 
                                                case TGA_RLERGB:
530
 
                                                {
531
 
                                                        int x = 0;
532
 
                                                        int y = 0;
533
 
                                                        BYTE rle;
534
 
                                                        WORD pixel;
535
 
 
536
 
                                                        while(1) {
537
 
                                                                BYTE *bits;
538
 
                                                                
539
 
                                                                if (fliphoriz)
540
 
                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
541
 
                                                                else
542
 
                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
543
 
                
544
 
                                                                io->read_proc(&rle,1, 1, handle);
545
 
                                                                
546
 
                                                                // compressed block
547
 
                                                                
548
 
                                                                if (rle > 127) {
549
 
                                                                        rle -= 127;
550
 
 
551
 
                                                                        io->read_proc(&pixel, sizeof(WORD), 1, handle);
552
 
#ifdef FREEIMAGE_BIGENDIAN
553
 
                                                                        SwapShort(&pixel);
554
 
#endif
555
 
                                                                
556
 
                                                                        for (int ix = 0; ix < rle; ix++) {
557
 
                                                                                if (TARGA_LOAD_RGB888 & flags) {
558
 
                                                                                        bits[x + FI_RGBA_BLUE]  = (BYTE)((((pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
559
 
                                                                                        bits[x + FI_RGBA_GREEN] = (BYTE)((((pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
560
 
                                                                                        bits[x + FI_RGBA_RED]   = (BYTE)((((pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
561
 
                                                                                } else {
562
 
                                                                                        *reinterpret_cast<WORD *>(bits + x) = 0x7FFF & pixel;
563
 
                                                                                }
564
 
 
565
 
                                                                                x += pixel_size;
566
 
                                                                                
567
 
                                                                                if (x >= line) {
568
 
                                                                                        x = 0;
569
 
                                                                                        y++;
570
 
 
571
 
                                                                                        if (y >= header.is_height)
572
 
                                                                                                goto done2;                                                                                                                             
573
 
                                                                                }
574
 
                                                                        }
575
 
                                                                } else {
576
 
                                                                        rle++;
577
 
 
578
 
                                                                        for (int ix = 0; ix < rle; ix++) {
579
 
                                                                                io->read_proc(&pixel, sizeof(WORD), 1, handle);
580
 
#ifdef FREEIMAGE_BIGENDIAN
581
 
                                                                                SwapShort(&pixel);
582
 
#endif
583
 
 
584
 
                                                                                if (TARGA_LOAD_RGB888 & flags) {
585
 
                                                                                        bits[x + FI_RGBA_BLUE]  = (BYTE)((((pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
586
 
                                                                                        bits[x + FI_RGBA_GREEN] = (BYTE)((((pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
587
 
                                                                                        bits[x + FI_RGBA_RED]   = (BYTE)((((pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
588
 
                                                                                } else {
589
 
                                                                                        *reinterpret_cast<WORD*>(bits + x) = 0x7FFF & pixel;
590
 
                                                                                }
591
 
 
592
 
                                                                                x += pixel_size;
593
 
 
594
 
                                                                                if (x >= line) {
595
 
                                                                                        x = 0;
596
 
                                                                                        y++;
597
 
 
598
 
                                                                                        if (y >= header.is_height)
599
 
                                                                                                goto done2;                                                                                                                             
600
 
                                                                                }
601
 
                                                                        }
602
 
                                                                }
603
 
                                                        }
604
 
 
605
 
                                        done2 :
606
 
                                                        break;
607
 
                                                }
608
 
 
609
 
                                                default :
610
 
                                                        FreeImage_Unload(dib);
611
 
                                                        return NULL;
 
695
 
 
696
                                                                        if(x >= line){
 
697
                                                                                x = 0;
 
698
                                                                                y++;
 
699
                                                                                if (fliphoriz) {
 
700
                                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
701
                                                                                } else {
 
702
                                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
 
703
                                                                                }
 
704
                                                                        }
 
705
 
 
706
                                                                }//< rle_count
 
707
                                                        }//< has_rle
 
708
                                                }//< while
 
709
 
 
710
                                                cacheIO_free(&cache);
 
711
                                                break;
 
712
                                        }
 
713
 
 
714
                                        default :
 
715
                                                FreeImage_Unload(dib);
 
716
                                                return NULL;
612
717
                                        }
613
718
 
614
719
                                        break;
618
723
                                {
619
724
                                        dib = FreeImage_Allocate(header.is_width, header.is_height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
620
725
 
621
 
                                        if (dib == 0)
622
 
                                                throw "DIB allocation failed";                                  
 
726
                                        if (dib == NULL) {
 
727
                                                throw FI_MSG_ERROR_DIB_MEMORY;
 
728
                                        }
623
729
 
624
730
                                        // read in the bitmap bits
625
731
 
626
732
                                        switch (header.image_type) {
627
 
                                                case TGA_RGB:
 
733
                                                case TGA_RGB://(24 bit)
628
734
                                                {
629
 
                                                        FILE_BGR bgr;
630
 
                                                        if (fliphoriz)
 
735
                                                        FILE_BGR* bgr_line = (FILE_BGR*)malloc(header.is_width * sizeof(FILE_BGR));
 
736
                                                        if(!bgr_line) throw FI_MSG_ERROR_MEMORY;
 
737
 
 
738
                                                        if (fliphoriz) {
631
739
                                                                for (unsigned count = header.is_height; count > 0; count--) {
632
740
                                                                        BYTE *bits = Internal_GetScanLine(dib, count-1, flipvert);
 
741
                                                                        io->read_proc(bgr_line, sizeof(FILE_BGR), header.is_width, handle);
633
742
 
 
743
                                                                        FILE_BGR *bgr = bgr_line;
634
744
                                                                        for (int x = 0; x < line; x += 3) {
635
 
                                                                                io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
636
 
 
637
 
                                                                                bits[x + FI_RGBA_BLUE]  = bgr.b;
638
 
                                                                                bits[x + FI_RGBA_GREEN] = bgr.g;
639
 
                                                                                bits[x + FI_RGBA_RED]   = bgr.r;
 
745
                                                                                bits[x + FI_RGBA_BLUE]  = bgr->b;
 
746
                                                                                bits[x + FI_RGBA_GREEN] = bgr->g;
 
747
                                                                                bits[x + FI_RGBA_RED]   = bgr->r;
 
748
                                                                                bgr++;
640
749
                                                                        }
641
750
                                                                }
642
 
                                                        else
 
751
 
 
752
                                                        } else {
643
753
                                                                for (unsigned count = 0; count < header.is_height; count++) {
644
754
                                                                        BYTE *bits = Internal_GetScanLine(dib, count, flipvert);
 
755
                                                                        io->read_proc(bgr_line, sizeof(FILE_BGR), header.is_width, handle);
645
756
 
 
757
                                                                        FILE_BGR *bgr = bgr_line;
646
758
                                                                        for (int x = 0; x < line; x += 3) {
647
 
                                                                                io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
648
 
 
649
 
                                                                                bits[x + FI_RGBA_BLUE]  = bgr.b;
650
 
                                                                                bits[x + FI_RGBA_GREEN] = bgr.g;
651
 
                                                                                bits[x + FI_RGBA_RED]   = bgr.r;
 
759
                                                                                bits[x + FI_RGBA_BLUE]  = bgr->b;
 
760
                                                                                bits[x + FI_RGBA_GREEN] = bgr->g;
 
761
                                                                                bits[x + FI_RGBA_RED]   = bgr->r;
 
762
                                                                                bgr++;
652
763
                                                                        }
653
764
                                                                }
 
765
                                                        }
654
766
 
 
767
                                                        free(bgr_line);
655
768
                                                        break;
656
769
                                                }
657
770
 
658
 
                                                case TGA_RLERGB:
 
771
                                                case TGA_RLERGB://(24 bit)
659
772
                                                {
660
 
                                                        int x = 0;
661
 
                                                        int y = 0;
 
773
 
662
774
                                                        BYTE rle;
663
775
                                                        BYTE *bits;
664
 
                                                        
665
 
                                                        if (fliphoriz)
 
776
 
 
777
                                                        // Compute the *rough* size of a line...
 
778
                                                        long pixels_offset = io->tell_proc(handle);
 
779
                                                        long sz = ((eof - pixels_offset) / header.is_height);
 
780
 
 
781
                                                        // ...and allocate cache of this size (yields best results)
 
782
                                                        CacheIO cache;
 
783
                                                        cacheIO_alloc(&cache, io, handle, sz);
 
784
 
 
785
                                                        int x = 0, y = 0;
 
786
                                                        if (fliphoriz) {
666
787
                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
667
 
                                                        else
 
788
                                                        } else {
668
789
                                                                bits = Internal_GetScanLine(dib, y, flipvert);
669
 
                                                        
670
 
                                                        if (alphabits) {
671
 
                                                                while(1) {
672
 
                                                                        io->read_proc(&rle,1, 1, handle);
673
 
                                                                        
674
 
                                                                        if (rle>127) {
675
 
                                                                                rle -= 127;
676
 
 
677
 
                                                                                FILE_BGRA bgra;
678
 
 
679
 
                                                                                io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
680
 
 
681
 
                                                                                for (int ix = 0; ix < rle; ix++) {
682
 
                                                                                        bits[x + FI_RGBA_BLUE]  = bgra.b;
683
 
                                                                                        bits[x + FI_RGBA_GREEN] = bgra.g;
684
 
                                                                                        bits[x + FI_RGBA_RED]   = bgra.r;
685
 
                                                                                        bits[x + FI_RGBA_ALPHA] = bgra.a;
686
 
                                                                                        x += 4;
687
 
 
688
 
                                                                                        if (x >= line) {
689
 
                                                                                                x = 0;
690
 
                                                                                                y++;
691
 
 
692
 
                                                                                                if (y >= header.is_height)
693
 
                                                                                                        goto done243;
694
 
 
695
 
                                                                                                if (fliphoriz)
696
 
                                                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
697
 
                                                                                                else
698
 
                                                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
699
 
                                                                                        }
700
 
                                                                                }
701
 
                                                                        } else {
702
 
                                                                                rle++;
703
 
 
704
 
                                                                                for (int ix = 0; ix < rle; ix++) {
705
 
                                                                                        FILE_BGRA bgra;
706
 
 
707
 
                                                                                        io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
708
 
 
709
 
                                                                                        bits[x + FI_RGBA_BLUE]  = bgra.b;
710
 
                                                                                        bits[x + FI_RGBA_GREEN] = bgra.g;
711
 
                                                                                        bits[x + FI_RGBA_RED]   = bgra.r;
712
 
                                                                                        bits[x + FI_RGBA_ALPHA] = bgra.a;
713
 
                                                                                        x += 4;
714
 
                                                                                        
715
 
                                                                                        if (x >= line) {
716
 
                                                                                                x = 0;
717
 
                                                                                                y++;
718
 
 
719
 
                                                                                                if (y >= header.is_height)
720
 
                                                                                                        goto done243;                                                                                   
721
 
 
722
 
                                                                                                if (fliphoriz)
723
 
                                                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
724
 
                                                                                                else
725
 
                                                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
726
 
                                                                                        }
727
 
                                                                                }
728
 
                                                                        }
729
 
                                                                }
730
 
                                                        } else {
731
 
                                                                while (1) {
732
 
                                                                        io->read_proc(&rle,1, 1, handle);
733
 
                                                                        
734
 
                                                                        if (rle>127) {
735
 
                                                                                rle -= 127;
736
 
 
737
 
                                                                                FILE_BGR bgr;
738
 
 
739
 
                                                                                io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
740
 
 
741
 
                                                                                for (int ix = 0; ix < rle; ix++) {
742
 
                                                                                        bits[x + FI_RGBA_BLUE]  = bgr.b;
743
 
                                                                                        bits[x + FI_RGBA_GREEN] = bgr.g;
744
 
                                                                                        bits[x + FI_RGBA_RED]   = bgr.r;
745
 
                                                                                        x += 3;
746
 
 
747
 
                                                                                        if (x >= line) {
748
 
                                                                                                x = 0;
749
 
                                                                                                y++;
750
 
 
751
 
                                                                                                if (y >= header.is_height)
752
 
                                                                                                        goto done243;                                                                                   
753
 
                                                                                                
754
 
                                                                                                if (fliphoriz)
755
 
                                                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
756
 
                                                                                                else
757
 
                                                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
758
 
                                                                                        }
759
 
                                                                                }
760
 
                                                                        } else {
761
 
                                                                                rle++;
762
 
 
763
 
                                                                                for (int ix = 0; ix < rle; ix++) {
764
 
                                                                                        FILE_BGR bgr;           
765
 
 
766
 
                                                                                        io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
767
 
 
768
 
                                                                                        bits[x + FI_RGBA_BLUE]  = bgr.b;
769
 
                                                                                        bits[x + FI_RGBA_GREEN] = bgr.g;
770
 
                                                                                        bits[x + FI_RGBA_RED]   = bgr.r;
771
 
                                                                                        x += 3;
772
 
                                                                                        
773
 
                                                                                        if (x >= line) {
774
 
                                                                                                x = 0;
775
 
                                                                                                y++;
776
 
 
777
 
                                                                                                if (y >= header.is_height)
778
 
                                                                                                        goto done243;                                                                                   
779
 
 
780
 
                                                                                                if (fliphoriz)
781
 
                                                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
782
 
                                                                                                else
783
 
                                                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
784
 
                                                                                        }
785
 
                                                                                }
786
 
                                                                        }
787
 
                                                                }
788
790
                                                        }
789
 
                                        done243 :
 
791
 
 
792
                                                        while( y < header.is_height) {
 
793
                                                                rle = cacheIO_getByte(&cache);
 
794
 
 
795
                                                                BOOL has_rle = rle & 0x80;
 
796
                                                                rle &= ~0x80; //remove type-bit
 
797
 
 
798
                                                                BYTE rle_count = rle + 1;
 
799
 
 
800
                                                                if (has_rle) {
 
801
 
 
802
                                                                        FILE_BGR *val = (FILE_BGR*)cacheIO_getBytes(&cache, sizeof(FILE_BGR));
 
803
 
 
804
                                                                        for (int ix = 0; ix < rle_count; ix++) {
 
805
                                                                                bits[x + FI_RGBA_BLUE]  = val->b;
 
806
                                                                                bits[x + FI_RGBA_GREEN] = val->g;
 
807
                                                                                bits[x + FI_RGBA_RED]   = val->r;
 
808
 
 
809
                                                                                x += 3;
 
810
 
 
811
                                                                                if(x >= line){
 
812
                                                                                        x = 0;
 
813
                                                                                        y++;
 
814
 
 
815
                                                                                        if (fliphoriz) {
 
816
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
817
                                                                                        } else {
 
818
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
 
819
                                                                                        }
 
820
                                                                                }
 
821
                                                                        }//<rle_count
 
822
                                                                } else { //<!has_rle
 
823
 
 
824
                                                                        for (int ix = 0; ix < rle_count; ix++) {
 
825
                                                                                FILE_BGR *val = (FILE_BGR*)cacheIO_getBytes(&cache, sizeof(FILE_BGR));
 
826
 
 
827
                                                                                bits[x + FI_RGBA_BLUE]  = val->b;
 
828
                                                                                bits[x + FI_RGBA_GREEN] = val->g;
 
829
                                                                                bits[x + FI_RGBA_RED]   = val->r;
 
830
 
 
831
                                                                                x += 3;
 
832
 
 
833
                                                                                if(x >= line){
 
834
                                                                                        x = 0;
 
835
                                                                                        y++;
 
836
 
 
837
                                                                                        if (fliphoriz) {
 
838
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
839
                                                                                        } else {
 
840
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
 
841
                                                                                        }
 
842
                                                                                }
 
843
 
 
844
                                                                        }//< rle_count
 
845
                                                                }//< has_rle
 
846
                                                        }//< while
 
847
 
 
848
                                                        cacheIO_free(&cache);
790
849
                                                        break;
791
850
                                                }
792
851
 
797
856
 
798
857
                                        break;
799
858
                                }
800
 
                                
 
859
 
801
860
                                case 32 :
802
861
                                {
803
862
                                        int pixel_bits;
804
863
 
805
864
                                        if (TARGA_LOAD_RGB888 & flags) {
806
865
                                                pixel_bits = 24;
807
 
 
808
 
                                                line = CalculateLine(header.is_width, pixel_bits);
809
 
                                                pitch = CalculatePitch(line);
810
866
                                        } else {
811
867
                                                pixel_bits = 32;
812
868
                                        }
814
870
                                        const unsigned pixel_size = unsigned (pixel_bits) / 8;
815
871
 
816
872
                                        // Allocate the DIB
 
873
                                        dib = FreeImage_Allocate(header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
817
874
 
818
 
                                        if( pixel_bits == 24 ) {
819
 
                                                dib = FreeImage_Allocate(header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
820
 
                                        } else {
821
 
                                                dib = FreeImage_Allocate(header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
 
875
                                        if (dib == NULL) {
 
876
                                                throw FI_MSG_ERROR_DIB_MEMORY;
822
877
                                        }
823
 
                                        
824
 
                                        if (dib == 0)
825
 
                                                throw "DIB allocation failed";                                  
826
878
 
827
879
                                        // read in the bitmap bits
828
880
 
829
881
                                        switch (header.image_type) {
830
 
                                                case TGA_RGB:
831
 
                                                {
832
 
                                                        // uncompressed
833
 
 
834
 
                                                        if (alphabits) {
835
 
                                                                if (fliphoriz)
836
 
                                                                        for (unsigned count = header.is_height; count > 0; count--) {
837
 
                                                                                BYTE *bits = bits = Internal_GetScanLine(dib, count-1, flipvert);
838
 
 
839
 
                                                                                for (unsigned cols = 0; cols < header.is_width; cols++) {
840
 
                                                                                        FILE_BGRA bgra;
841
 
 
842
 
                                                                                        io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
843
 
 
844
 
                                                                                        if ((TARGA_LOAD_RGB888 & flags) != TARGA_LOAD_RGB888) {
845
 
                                                                                                bits[FI_RGBA_BLUE]      = bgra.b;
846
 
                                                                                                bits[FI_RGBA_GREEN] = bgra.g;
847
 
                                                                                                bits[FI_RGBA_RED]       = bgra.r;
848
 
                                                                                                bits[FI_RGBA_ALPHA] = bgra.a;
849
 
                                                                                        } else {
850
 
                                                                                                bits[FI_RGBA_BLUE]      = bgra.b;
851
 
                                                                                                bits[FI_RGBA_GREEN] = bgra.g;
852
 
                                                                                                bits[FI_RGBA_RED]       = bgra.r;
853
 
                                                                                        }
854
 
 
855
 
                                                                                        bits += pixel_size;
856
 
                                                                                }
857
 
                                                                        }
858
 
                                                                else
859
 
                                                                        for (unsigned count = 0; count < header.is_height; count++) {
860
 
                                                                                BYTE *bits = Internal_GetScanLine(dib, count, flipvert);
861
 
 
862
 
                                                                                for (unsigned cols = 0; cols < header.is_width; cols++) {
863
 
                                                                                        FILE_BGRA bgra;
864
 
 
865
 
                                                                                        io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
866
 
 
867
 
                                                                                        if ((TARGA_LOAD_RGB888 & flags) != TARGA_LOAD_RGB888) {
868
 
                                                                                                bits[FI_RGBA_BLUE]      = bgra.b;
869
 
                                                                                                bits[FI_RGBA_GREEN] = bgra.g;
870
 
                                                                                                bits[FI_RGBA_RED]       = bgra.r;
871
 
                                                                                                bits[FI_RGBA_ALPHA] = bgra.a;
872
 
                                                                                        } else {
873
 
                                                                                                bits[FI_RGBA_BLUE]      = bgra.b;
874
 
                                                                                                bits[FI_RGBA_GREEN] = bgra.g;
875
 
                                                                                                bits[FI_RGBA_RED]       = bgra.r;
876
 
                                                                                        }
877
 
 
878
 
                                                                                        bits += pixel_size;
879
 
                                                                                }
880
 
                                                                        }
881
 
 
 
882
                                        case TGA_RGB://(32 bit)
 
883
                                        {
 
884
                                                // uncompressed
 
885
 
 
886
                                                // in_line cache
 
887
                                                FILE_BGRA* in_line = (FILE_BGRA*)malloc(header.is_width * 4);
 
888
                                                if(!in_line) throw FI_MSG_ERROR_MEMORY;
 
889
 
 
890
                                                const int w = header.is_width;  // yes, it does make a (minor) difference
 
891
                                                const int h = header.is_height; // to move these outside
 
892
 
 
893
                                                for (int y = 0; y < h; y++) {
 
894
                                                        BYTE *bits;
 
895
 
 
896
                                                        if (fliphoriz) {
 
897
                                                                bits = Internal_GetScanLine(dib, h - y - 1, flipvert);
882
898
                                                        } else {
883
 
 
884
 
                                                                for (unsigned count = 0; count < header.is_height; count++) {
885
 
                                                                        BYTE *bits;
886
 
 
887
 
                                                                        if (fliphoriz)
888
 
                                                                                bits = Internal_GetScanLine(dib, header.is_height - count - 1, flipvert);
889
 
                                                                        else
890
 
                                                                                bits = Internal_GetScanLine(dib, count, flipvert);
891
 
 
892
 
                                                                        for (unsigned cols = 0; cols < header.is_width; cols++) {
893
 
                                                                                FILE_BGRA bgra;
894
 
 
895
 
                                                                                io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
896
 
 
897
 
                                                                                if ((TARGA_LOAD_RGB888 & flags) != TARGA_LOAD_RGB888) {
898
 
                                                                                        bits[FI_RGBA_BLUE]      = bgra.b;
899
 
                                                                                        bits[FI_RGBA_GREEN] = bgra.g;
900
 
                                                                                        bits[FI_RGBA_RED]       = bgra.r;
901
 
                                                                                        bits[FI_RGBA_ALPHA] = bgra.a;
902
 
                                                                                } else {
903
 
                                                                                        bits[FI_RGBA_BLUE]      = bgra.b;
904
 
                                                                                        bits[FI_RGBA_GREEN]     = bgra.g;
905
 
                                                                                        bits[FI_RGBA_RED]       = bgra.r;
906
 
                                                                                }
907
 
 
908
 
                                                                                bits += pixel_size;
909
 
                                                                        }
910
 
                                                                }
911
 
                                                        }
912
 
 
913
 
                                                        break;
914
 
                                                }
915
 
                                                case TGA_RLERGB:
916
 
                                                {
917
 
                                                        int x = 0;
918
 
                                                        int y = 0;
919
 
                                                        BYTE rle;
920
 
                                                        BYTE *bits;
921
 
                                                        
922
 
                                                        if (fliphoriz)
923
 
                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
924
 
                                                        else
925
899
                                                                bits = Internal_GetScanLine(dib, y, flipvert);
926
 
                                                        
927
 
                                                        while(1) {
928
 
                                                                io->read_proc(&rle,1, 1, handle);
 
900
                                                        }
 
901
 
 
902
                                                        io->read_proc(in_line, 4, w, handle);
 
903
 
 
904
                                                        FILE_BGRA *bgra = in_line;
 
905
                                                        for (int x = 0; x < w; x++) {
 
906
                                                                bits[FI_RGBA_BLUE]      = bgra->b;
 
907
                                                                bits[FI_RGBA_GREEN] = bgra->g;
 
908
                                                                bits[FI_RGBA_RED]       = bgra->r;
 
909
 
 
910
                                                                if ((TARGA_LOAD_RGB888 & flags) != TARGA_LOAD_RGB888) {
 
911
                                                                        bits[FI_RGBA_ALPHA] = bgra->a;
 
912
                                                                }
 
913
 
 
914
                                                                bgra++;
 
915
                                                                bits += pixel_size;
 
916
                                                        }
 
917
                                                }
 
918
 
 
919
                                                free(in_line);
 
920
                                                break;
 
921
                                        }
 
922
                                        case TGA_RLERGB://(32 bit)
 
923
                                        {
 
924
                                                BYTE rle;
 
925
                                                BYTE *bits;
 
926
 
 
927
                                                // Compute the *rough* size of a line...
 
928
                                                long pixels_offset = io->tell_proc(handle);
 
929
                                                long sz = ((eof - pixels_offset) / header.is_height);
 
930
 
 
931
                                                // ...and allocate cache of this size (yields best results)
 
932
                                                CacheIO cache;
 
933
                                                cacheIO_alloc(&cache, io, handle, sz);
 
934
 
 
935
                                                int x = 0, y = 0;
 
936
                                                if (fliphoriz) {
 
937
                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
938
                                                } else {
 
939
                                                        bits = Internal_GetScanLine(dib, y, flipvert);
 
940
                                                }
 
941
 
 
942
                                                while( y < header.is_height) {
 
943
 
 
944
                                                        rle = cacheIO_getByte(&cache);
 
945
 
 
946
                                                        BOOL has_rle = rle & 0x80;
 
947
                                                        rle &= ~0x80; // remove type-bit
 
948
 
 
949
                                                        BYTE rle_count = rle + 1;
 
950
 
 
951
                                                        if (has_rle) {
 
952
 
 
953
                                                                FILE_BGRA *val = (FILE_BGRA*)cacheIO_getBytes(&cache, sizeof(FILE_BGRA));
 
954
 
 
955
                                                                for (int ix = 0; ix < rle_count; ix++) {
 
956
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
 
957
                                                                        *(reinterpret_cast<unsigned*>(bits+x)) = *(reinterpret_cast<unsigned*> (val));
 
958
#else // NOTE This is faster then doing reinterpret_cast + INPLACESWAP for RGB!
 
959
                                                                        bits[x + FI_RGBA_BLUE]  = val->b;
 
960
                                                                        bits[x + FI_RGBA_GREEN] = val->g;
 
961
                                                                        bits[x + FI_RGBA_RED]   = val->r;
 
962
                                                                        bits[x + FI_RGBA_ALPHA] = val->a;
 
963
#endif
 
964
                                                                        x += 4;
 
965
 
 
966
                                                                        if(x >= line) {
 
967
                                                                                x = 0;
 
968
                                                                                y++;
 
969
 
 
970
                                                                                if (fliphoriz) {
 
971
                                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
972
                                                                                } else {
 
973
                                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
 
974
                                                                                }
 
975
                                                                        }
 
976
                                                                }
 
977
                                                        } else {//<!has_rle
 
978
 
 
979
                                                                for (int ix = 0; ix < rle_count; ix++) {
 
980
                                                                        FILE_BGRA *val = (FILE_BGRA*)cacheIO_getBytes(&cache, sizeof(FILE_BGRA));
 
981
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
 
982
                                                                        *(reinterpret_cast<unsigned*>(bits+x)) = *(reinterpret_cast<unsigned*> (val));
 
983
#else
 
984
                                                                        bits[x + FI_RGBA_BLUE]  = val->b;
 
985
                                                                        bits[x + FI_RGBA_GREEN] = val->g;
 
986
                                                                        bits[x + FI_RGBA_RED]   = val->r;
 
987
                                                                        bits[x + FI_RGBA_ALPHA] = val->a;
 
988
#endif
 
989
                                                                        x += 4;
929
990
                                                                        
930
 
                                                                if (rle>127) {
931
 
                                                                        rle -= 127;
932
 
 
933
 
                                                                        FILE_BGRA bgra;
934
 
 
935
 
                                                                        io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
936
 
 
937
 
                                                                        for (int ix = 0; ix < rle; ix++) {
938
 
                                                                                bits[x + FI_RGBA_BLUE]  = bgra.b;
939
 
                                                                                bits[x + FI_RGBA_GREEN] = bgra.g;
940
 
                                                                                bits[x + FI_RGBA_RED]   = bgra.r;
941
 
                                                                                bits[x + FI_RGBA_ALPHA] = bgra.a;
942
 
                                                                                x += 4;
943
 
 
944
 
                                                                                if (x >= line) {
945
 
                                                                                        x = 0;
946
 
                                                                                        y++;
947
 
 
948
 
                                                                                        if (y >= header.is_height)
949
 
                                                                                                goto done3210;
950
 
 
951
 
                                                                                        if (fliphoriz)
952
 
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
953
 
                                                                                        else
954
 
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
955
 
                                                                                }
956
 
                                                                        }
957
 
                                                                } else {
958
 
                                                                        rle++;
959
 
 
960
 
                                                                        for (int ix = 0; ix < rle; ix++) {
961
 
                                                                                FILE_BGRA bgra;
962
 
 
963
 
                                                                                io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
964
 
 
965
 
                                                                                bits[x + FI_RGBA_BLUE]  = bgra.b;
966
 
                                                                                bits[x + FI_RGBA_GREEN] = bgra.g;
967
 
                                                                                bits[x + FI_RGBA_RED]   = bgra.r;
968
 
                                                                                bits[x + FI_RGBA_ALPHA] = bgra.a;
969
 
                                                                                x += 4;
970
 
                                                                                        
971
 
                                                                                if (x >= line) {
972
 
                                                                                        x = 0;
973
 
                                                                                        y++;
974
 
 
975
 
                                                                                        if (y >= header.is_height)
976
 
                                                                                                goto done3210;
977
 
 
978
 
                                                                                        if (fliphoriz)
979
 
                                                                                                bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
980
 
                                                                                        else
981
 
                                                                                                bits = Internal_GetScanLine(dib, y, flipvert);
982
 
                                                                                }
983
 
                                                                        }
984
 
                                                                }
985
 
                                                        }
986
 
 
987
 
                                        done3210 :
988
 
                                                        break;
989
 
                                                }
990
 
 
991
 
                                                default :
992
 
                                                        FreeImage_Unload(dib);
993
 
                                                        return NULL;
 
991
                                                                        if(x >= line){
 
992
                                                                                x = 0;
 
993
                                                                                y++;
 
994
                                                                                
 
995
                                                                                if (fliphoriz) {
 
996
                                                                                        bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
 
997
                                                                                } else {
 
998
                                                                                        bits = Internal_GetScanLine(dib, y, flipvert);
 
999
                                                                                }
 
1000
                                                                        }
 
1001
 
 
1002
                                                                }//< rle_count
 
1003
                                                        }//< has_rle
 
1004
                                                }//< while y
 
1005
 
 
1006
                                                cacheIO_free(&cache);
 
1007
                                                break;
 
1008
                                        }
 
1009
 
 
1010
                                        default :
 
1011
                                                FreeImage_Unload(dib);
 
1012
                                                return NULL;
994
1013
                                        }
995
1014
 
996
1015
                                        break;
1053
1072
                SwapHeader(&header);
1054
1073
#endif
1055
1074
 
1056
 
                // write the palette    
 
1075
                // write the palette
1057
1076
 
1058
1077
                if (palette) {
1059
1078
                        if(FreeImage_IsTransparent(dib)) {