84
85
// Internal functions
85
86
// ==========================================================
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.
95
typedef struct tagCacheIO {
100
FreeImageIO *io; // not necessary, but
101
fi_handle handle; // passing them as args is slower
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!
111
cacheIO_alloc(CacheIO *ch, FreeImageIO *io, fi_handle handle, size_t size) {
113
ch->home = (BYTE*)malloc(size);
114
if(ch->home == NULL) {
117
ch->end = ch->home + size;
121
ch->ptr = ch->end; //will force refill on first access
127
cacheIO_free(CacheIO *ch) {
128
if(ch->home != NULL) {
134
cacheIO_getByte(CacheIO *ch) {
135
if(ch->ptr >= ch->end) {
137
ch->io->read_proc(ch->ptr, sizeof(BYTE), (unsigned)ch->size, ch->handle);//### EOF - no problem?
139
BYTE result = *ch->ptr;
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);
152
ch->io->read_proc(ch->ptr, sizeof(BYTE), (unsigned)ch->size, ch->handle);//### EOF - no problem?
154
BYTE *result = ch->ptr;
88
161
Internal_GetScanLine(FIBITMAP *dib, int scanline, int flipvert) {
89
162
//assert ((scanline >= 0) && (scanline < (int)FreeImage_GetHeight(dib)));
92
165
return FreeImage_GetScanLine(dib, scanline);
94
167
return FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - scanline - 1);
97
171
#ifdef FREEIMAGE_BIGENDIAN
371
453
io->read_proc(bits, sizeof(BYTE), line, handle);
378
460
case TGA_RLECMAP:
461
case TGA_RLEMONO: //(8 bit)
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);
470
// ...and allocate cache of this size (yields best results)
472
cacheIO_alloc(&cache, io, handle, sz);
387
477
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
389
479
bits = Internal_GetScanLine(dib, y, flipvert);
392
io->read_proc(&rle,1, 1, handle);
399
io->read_proc(&triple, 1, 1, handle);
401
for (int ix = 0; ix < rle; ix++) {
409
if (y >= header.is_height)
413
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
415
bits = Internal_GetScanLine(dib, y, flipvert);
421
for (int ix = 0; ix < rle; ix++) {
424
io->read_proc(&triple, 1, 1, handle);
433
if (y >= header.is_height)
437
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
439
bits = Internal_GetScanLine(dib, y, flipvert);
482
while(y < header.is_height) {
484
rle = cacheIO_getByte(&cache);
486
BOOL has_rle = rle & 0x80;
487
rle &= ~0x80; // remove type-bit
489
BYTE rle_count = rle + 1;
493
BYTE val = cacheIO_getByte(&cache);
495
for(int ix = 0; ix < rle_count; ix++) {
502
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
504
bits = Internal_GetScanLine(dib, y, flipvert);
511
for(int ix = 0; ix < rle_count; ix++) {
513
BYTE val = cacheIO_getByte(&cache);
519
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
521
bits = Internal_GetScanLine(dib, y, flipvert);
528
cacheIO_free(&cache);
449
533
FreeImage_Unload(dib);
463
547
if (TARGA_LOAD_RGB888 & flags) {
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);
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);
474
throw "DIB allocation failed";
556
throw FI_MSG_ERROR_DIB_MEMORY;
476
559
int line = CalculateLine(header.is_width, pixel_bits);
478
561
const unsigned pixel_size = unsigned(pixel_bits) / 8;
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
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 */
490
574
io->seek_proc(handle, start_offset, SEEK_SET);
491
575
io->seek_proc(handle, sizeof(tagTGAHEADER) + header.id_length + garblen, SEEK_SET);
493
577
// read in the bitmap bits
497
579
switch (header.image_type) {
500
for (int y = 0; y < header.is_height; y++) {
504
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
506
bits = Internal_GetScanLine(dib, y, flipvert);
508
for (int x = 0; x < line; ) {
509
io->read_proc(&pixel, sizeof(WORD), 1, handle);
510
#ifdef FREEIMAGE_BIGENDIAN
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);
519
*reinterpret_cast<WORD*>(bits + x) = 0x7FFF & pixel;
580
case TGA_RGB: //(16 bit)
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;
586
const int h = header.is_height;
587
for (int y = 0; y < h; y++) {
591
bits = Internal_GetScanLine(dib, h - y - 1, flipvert);
593
bits = Internal_GetScanLine(dib, y, flipvert);
595
io->read_proc(in_line, sizeof(WORD), header.is_width, handle);
597
WORD *pixel = in_line;
598
for (int x = 0; x < line; x += pixel_size) {
600
#ifdef FREEIMAGE_BIGENDIAN
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);
609
*reinterpret_cast<WORD*>(bits + x) = 0x7FFF & *pixel;
619
case TGA_RLERGB: //(16 bit)
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);
628
// ...and allocate cache of this size (yields best results)
630
cacheIO_alloc(&cache, io, handle, sz);
635
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
637
bits = Internal_GetScanLine(dib, y, flipvert);
640
while( y < header.is_height) {
641
rle = cacheIO_getByte(&cache);
643
BOOL has_rle = rle & 0x80;
644
rle &= ~0x80; //remove type-bit
646
int rle_count = rle + 1;
650
WORD *val = (WORD*)cacheIO_getBytes(&cache, sizeof(WORD));
651
#ifdef FREEIMAGE_BIGENDIAN
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);
660
*reinterpret_cast<WORD *>(bits + x) = 0x7FFF & *val;
670
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
672
bits = Internal_GetScanLine(dib, y, flipvert);
679
for (int ix = 0; ix < rle_count; ix++) {
680
WORD *val = (WORD*)cacheIO_getBytes(&cache, sizeof(WORD));
682
#ifdef FREEIMAGE_BIGENDIAN
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);
691
*reinterpret_cast<WORD *>(bits + x) = 0x7FFF & *val;
540
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
542
bits = Internal_GetScanLine(dib, y, flipvert);
544
io->read_proc(&rle,1, 1, handle);
551
io->read_proc(&pixel, sizeof(WORD), 1, handle);
552
#ifdef FREEIMAGE_BIGENDIAN
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);
562
*reinterpret_cast<WORD *>(bits + x) = 0x7FFF & pixel;
571
if (y >= header.is_height)
578
for (int ix = 0; ix < rle; ix++) {
579
io->read_proc(&pixel, sizeof(WORD), 1, handle);
580
#ifdef FREEIMAGE_BIGENDIAN
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);
589
*reinterpret_cast<WORD*>(bits + x) = 0x7FFF & pixel;
598
if (y >= header.is_height)
610
FreeImage_Unload(dib);
700
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
702
bits = Internal_GetScanLine(dib, y, flipvert);
710
cacheIO_free(&cache);
715
FreeImage_Unload(dib);
619
724
dib = FreeImage_Allocate(header.is_width, header.is_height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
622
throw "DIB allocation failed";
727
throw FI_MSG_ERROR_DIB_MEMORY;
624
730
// read in the bitmap bits
626
732
switch (header.image_type) {
733
case TGA_RGB://(24 bit)
735
FILE_BGR* bgr_line = (FILE_BGR*)malloc(header.is_width * sizeof(FILE_BGR));
736
if(!bgr_line) throw FI_MSG_ERROR_MEMORY;
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);
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);
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;
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);
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);
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;
771
case TGA_RLERGB://(24 bit)
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);
781
// ...and allocate cache of this size (yields best results)
783
cacheIO_alloc(&cache, io, handle, sz);
666
787
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
668
789
bits = Internal_GetScanLine(dib, y, flipvert);
672
io->read_proc(&rle,1, 1, handle);
679
io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
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;
692
if (y >= header.is_height)
696
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
698
bits = Internal_GetScanLine(dib, y, flipvert);
704
for (int ix = 0; ix < rle; ix++) {
707
io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
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;
719
if (y >= header.is_height)
723
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
725
bits = Internal_GetScanLine(dib, y, flipvert);
732
io->read_proc(&rle,1, 1, handle);
739
io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
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;
751
if (y >= header.is_height)
755
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
757
bits = Internal_GetScanLine(dib, y, flipvert);
763
for (int ix = 0; ix < rle; ix++) {
766
io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
768
bits[x + FI_RGBA_BLUE] = bgr.b;
769
bits[x + FI_RGBA_GREEN] = bgr.g;
770
bits[x + FI_RGBA_RED] = bgr.r;
777
if (y >= header.is_height)
781
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
783
bits = Internal_GetScanLine(dib, y, flipvert);
792
while( y < header.is_height) {
793
rle = cacheIO_getByte(&cache);
795
BOOL has_rle = rle & 0x80;
796
rle &= ~0x80; //remove type-bit
798
BYTE rle_count = rle + 1;
802
FILE_BGR *val = (FILE_BGR*)cacheIO_getBytes(&cache, sizeof(FILE_BGR));
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;
816
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
818
bits = Internal_GetScanLine(dib, y, flipvert);
824
for (int ix = 0; ix < rle_count; ix++) {
825
FILE_BGR *val = (FILE_BGR*)cacheIO_getBytes(&cache, sizeof(FILE_BGR));
827
bits[x + FI_RGBA_BLUE] = val->b;
828
bits[x + FI_RGBA_GREEN] = val->g;
829
bits[x + FI_RGBA_RED] = val->r;
838
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
840
bits = Internal_GetScanLine(dib, y, flipvert);
848
cacheIO_free(&cache);
814
870
const unsigned pixel_size = unsigned (pixel_bits) / 8;
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);
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);
821
dib = FreeImage_Allocate(header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
876
throw FI_MSG_ERROR_DIB_MEMORY;
825
throw "DIB allocation failed";
827
879
// read in the bitmap bits
829
881
switch (header.image_type) {
836
for (unsigned count = header.is_height; count > 0; count--) {
837
BYTE *bits = bits = Internal_GetScanLine(dib, count-1, flipvert);
839
for (unsigned cols = 0; cols < header.is_width; cols++) {
842
io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
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;
850
bits[FI_RGBA_BLUE] = bgra.b;
851
bits[FI_RGBA_GREEN] = bgra.g;
852
bits[FI_RGBA_RED] = bgra.r;
859
for (unsigned count = 0; count < header.is_height; count++) {
860
BYTE *bits = Internal_GetScanLine(dib, count, flipvert);
862
for (unsigned cols = 0; cols < header.is_width; cols++) {
865
io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
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;
873
bits[FI_RGBA_BLUE] = bgra.b;
874
bits[FI_RGBA_GREEN] = bgra.g;
875
bits[FI_RGBA_RED] = bgra.r;
882
case TGA_RGB://(32 bit)
887
FILE_BGRA* in_line = (FILE_BGRA*)malloc(header.is_width * 4);
888
if(!in_line) throw FI_MSG_ERROR_MEMORY;
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
893
for (int y = 0; y < h; y++) {
897
bits = Internal_GetScanLine(dib, h - y - 1, flipvert);
884
for (unsigned count = 0; count < header.is_height; count++) {
888
bits = Internal_GetScanLine(dib, header.is_height - count - 1, flipvert);
890
bits = Internal_GetScanLine(dib, count, flipvert);
892
for (unsigned cols = 0; cols < header.is_width; cols++) {
895
io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
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;
903
bits[FI_RGBA_BLUE] = bgra.b;
904
bits[FI_RGBA_GREEN] = bgra.g;
905
bits[FI_RGBA_RED] = bgra.r;
923
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
925
899
bits = Internal_GetScanLine(dib, y, flipvert);
928
io->read_proc(&rle,1, 1, handle);
902
io->read_proc(in_line, 4, w, handle);
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;
910
if ((TARGA_LOAD_RGB888 & flags) != TARGA_LOAD_RGB888) {
911
bits[FI_RGBA_ALPHA] = bgra->a;
922
case TGA_RLERGB://(32 bit)
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);
931
// ...and allocate cache of this size (yields best results)
933
cacheIO_alloc(&cache, io, handle, sz);
937
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
939
bits = Internal_GetScanLine(dib, y, flipvert);
942
while( y < header.is_height) {
944
rle = cacheIO_getByte(&cache);
946
BOOL has_rle = rle & 0x80;
947
rle &= ~0x80; // remove type-bit
949
BYTE rle_count = rle + 1;
953
FILE_BGRA *val = (FILE_BGRA*)cacheIO_getBytes(&cache, sizeof(FILE_BGRA));
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;
971
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
973
bits = Internal_GetScanLine(dib, y, flipvert);
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));
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;
935
io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
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;
948
if (y >= header.is_height)
952
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
954
bits = Internal_GetScanLine(dib, y, flipvert);
960
for (int ix = 0; ix < rle; ix++) {
963
io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
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;
975
if (y >= header.is_height)
979
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
981
bits = Internal_GetScanLine(dib, y, flipvert);
992
FreeImage_Unload(dib);
996
bits = Internal_GetScanLine(dib, header.is_height - y - 1, flipvert);
998
bits = Internal_GetScanLine(dib, y, flipvert);
1006
cacheIO_free(&cache);
1011
FreeImage_Unload(dib);