Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
// read a pixel value from file...
BYTE *val = cache.getBytes(file_pixel_size);
//...and fill packet_count pixels with it
for (int ix = 0; ix < packet_count; ix++) {
_assignPixel<bPP>((line_bits+x), val, as24bit);
x += pixel_size;
if (x >= line_size) {
x = 0;
y++;
line_bits = FreeImage_GetScanLine(dib, y);
}
}
} else {
// no rle commpresion
// copy packet_count pixels from file to dib
for (int ix = 0; ix < packet_count; ix++) {
BYTE *val = cache.getBytes(file_pixel_size);
_assignPixel<bPP>((line_bits+x), val, as24bit);
x += pixel_size;
if (x >= line_size) {
x = 0;
y++;
line_bits = FreeImage_GetScanLine(dib, y);
}
} //< packet_count
} //< has_rle
} //< while height
}
// --------------------------------------------------------------------------
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
FIBITMAP *dib = NULL;
if (!handle) {
return NULL;
}
try {
const BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
// remember the start offset
long start_offset = io->tell_proc(handle);
// remember end-of-file (used for RLE cache)
io->seek_proc(handle, 0, SEEK_END);
long eof = io->tell_proc(handle);
io->seek_proc(handle, start_offset, SEEK_SET);
// read and process the bitmap's footer
TargaThumbnail thumbnail;
if(isTARGA20(io, handle)) {
TGAFOOTER footer;
const long footer_offset = start_offset + eof - sizeof(footer);
io->seek_proc(handle, footer_offset, SEEK_SET);
io->read_proc(&footer, sizeof(tagTGAFOOTER), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
SwapFooter(&footer);
#endif
BOOL hasExtensionArea = footer.extension_offset > 0;
if(hasExtensionArea) {
TGAEXTENSIONAREA extensionarea;
io->seek_proc(handle, footer.extension_offset, SEEK_SET);
io->read_proc(&extensionarea, sizeof(extensionarea), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
SwapExtensionArea(&extensionarea);
#endif
DWORD postage_stamp_offset = extensionarea.postage_stamp_offset;
BOOL hasThumbnail = (postage_stamp_offset > 0) && (postage_stamp_offset < (DWORD)footer_offset);
if(hasThumbnail) {
io->seek_proc(handle, postage_stamp_offset, SEEK_SET);
thumbnail.read(io, handle, footer_offset - postage_stamp_offset);
}
}
}
// read and process the bitmap's header
TGAHEADER header;
io->seek_proc(handle, start_offset, SEEK_SET);
io->read_proc(&header, sizeof(tagTGAHEADER), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
SwapHeader(&header);
#endif
thumbnail.setDepth(header.is_pixel_depth);
const int line = CalculateLine(header.is_width, header.is_pixel_depth);
const int pixel_bits = header.is_pixel_depth;
const int pixel_size = pixel_bits/8;
int fliphoriz = (header.is_image_descriptor & 0x10) ? 1 : 0;
int flipvert = (header.is_image_descriptor & 0x20) ? 1 : 0;
// skip comment
io->seek_proc(handle, header.id_length, SEEK_CUR);
switch (header.is_pixel_depth) {
case 8 : {
dib = FreeImage_AllocateHeader(header_only, header.is_width, header.is_height, 8);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// read the palette (even if header only)
RGBQUAD *palette = FreeImage_GetPalette(dib);
if (header.color_map_type > 0) {
unsigned count, csize;
// calculate the color map size
csize = header.cm_length * header.cm_size / 8;
// read the color map
BYTE *cmap = (BYTE*)malloc(csize * sizeof(BYTE));
if (cmap == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
io->read_proc(cmap, sizeof(BYTE), csize, handle);
// build the palette
switch (header.cm_size) {
case 16: {
WORD *rgb555 = (WORD*)&cmap[0];
unsigned start = (unsigned)header.cm_first_entry;
unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
for (count = start; count < stop; count++) {
palette[count].rgbRed = (BYTE)((((*rgb555 & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
palette[count].rgbGreen = (BYTE)((((*rgb555 & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
palette[count].rgbBlue = (BYTE)((((*rgb555 & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
rgb555++;
( run in 0.436 second using v1.01-cache-2.11-cpan-ceb78f64989 )