Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
// ==========================================================
// TARGA Loader and Writer
//
// Design and implementation by
// - Floris van den Berg (flvdberg@wxs.nl)
// - Jani Kajala (janik@remedy.fi)
// - Martin Weber (martweb@gmx.net)
// - Machiel ten Brinke (brinkem@uni-one.nl)
// - Peter Lemmens (peter.lemmens@planetinternet.be)
// - Hervé Drolon (drolon@infonie.fr)
// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================
#include "FreeImage.h"
#include "Utilities.h"
// ----------------------------------------------------------
// Constants + headers
// ----------------------------------------------------------
#ifdef _WIN32
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif
typedef struct tagTGAHEADER {
BYTE id_length; //! length of the image ID field
BYTE color_map_type; //! whether a color map is included
BYTE image_type; //! compression and color types
WORD cm_first_entry; //! first entry index (offset into the color map table)
WORD cm_length; //! color map length (number of entries)
BYTE cm_size; //! color map entry size, in bits (number of bits per pixel)
WORD is_xorigin; //! X-origin of image (absolute coordinate of lower-left corner for displays where origin is at the lower left)
WORD is_yorigin; //! Y-origin of image (as for X-origin)
WORD is_width; //! image width
WORD is_height; //! image height
BYTE is_pixel_depth; //! bits per pixel
BYTE is_image_descriptor; //! image descriptor, bits 3-0 give the alpha channel depth, bits 5-4 give direction
} TGAHEADER;
typedef struct tagTGAEXTENSIONAREA {
WORD extension_size; // Size in bytes of the extension area, always 495
char author_name[41]; // Name of the author. If not used, bytes should be set to NULL (\0) or spaces
char author_comments[324]; // A comment, organized as four lines, each consisting of 80 characters plus a NULL
WORD datetime_stamp[6]; // Date and time at which the image was created
char job_name[41]; // Job ID
WORD job_time[3]; // Hours, minutes and seconds spent creating the file (for billing, etc.)
char software_id[41]; // The application that created the file
BYTE software_version[3];
DWORD key_color;
WORD pixel_aspect_ratio[2];
WORD gamma_value[2];
DWORD color_correction_offset; // Number of bytes from the beginning of the file to the color correction table if present
DWORD postage_stamp_offset; // Number of bytes from the beginning of the file to the postage stamp image if present
DWORD scan_line_offset; // Number of bytes from the beginning of the file to the scan lines table if present
BYTE attributes_type; // Specifies the alpha channel
} TGAEXTENSIONAREA;
typedef struct tagTGAFOOTER {
DWORD extension_offset; // extension area offset : offset in bytes from the beginning of the file
DWORD developer_offset; // developer directory offset : offset in bytes from the beginning of the file
char signature[18]; // signature string : contains "TRUEVISION-XFILE.\0"
} TGAFOOTER;
#ifdef _WIN32
#pragma pack(pop)
#else
#pragma pack()
#endif
static const char *FI_MSG_ERROR_CORRUPTED = "Image data corrupted";
// ----------------------------------------------------------
// Image type
//
#define TGA_NULL 0 // no image data included
#define TGA_CMAP 1 // uncompressed, color-mapped image
#define TGA_RGB 2 // uncompressed, true-color image
#define TGA_MONO 3 // uncompressed, black-and-white image
#define TGA_RLECMAP 9 // run-length encoded, color-mapped image
#define TGA_RLERGB 10 // run-length encoded, true-color image
#define TGA_RLEMONO 11 // run-length encoded, black-and-white image
#define TGA_CMPCMAP 32 // compressed (Huffman/Delta/RLE) color-mapped image (e.g., VDA/D) - Obsolete
#define TGA_CMPCMAP4 33 // compressed (Huffman/Delta/RLE) color-mapped four pass image (e.g., VDA/D) - Obsolete
// ==========================================================
// Thumbnail functions
// ==========================================================
class TargaThumbnail
{
public:
TargaThumbnail() : _w(0), _h(0), _depth(0), _data(NULL) {
}
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
BOOL isNull() { return _begin == NULL;}
inline
BYTE getByte() {
if (_ptr >= _end) {
// need refill
_ptr = _begin;
_io->read_proc(_ptr, sizeof(BYTE), (unsigned)_size, _handle); //### EOF - no problem?
}
BYTE result = *_ptr;
_ptr++;
return result;
}
inline
BYTE* getBytes(size_t count /*must be < _size!*/) {
if (_ptr + count >= _end) {
// need refill
// 'count' bytes might span two cache bounds,
// SEEK back to add the remains of the current cache again into the new one
long read = long(_ptr - _begin);
long remaining = long(_size - read);
_io->seek_proc(_handle, -remaining, SEEK_CUR);
_ptr = _begin;
_io->read_proc(_ptr, sizeof(BYTE), (unsigned)_size, _handle); //### EOF - no problem?
}
BYTE *result = _ptr;
_ptr += count;
return result;
}
private:
IOCache& operator=(const IOCache& src); // deleted
IOCache(const IOCache& other); // deleted
private:
BYTE *_ptr;
BYTE *_begin;
BYTE *_end;
const size_t _size;
const FreeImageIO *_io;
const fi_handle _handle;
};
#ifdef FREEIMAGE_BIGENDIAN
static void
SwapHeader(TGAHEADER *header) {
SwapShort(&header->cm_first_entry);
SwapShort(&header->cm_length);
SwapShort(&header->is_xorigin);
SwapShort(&header->is_yorigin);
SwapShort(&header->is_width);
SwapShort(&header->is_height);
}
static void
SwapExtensionArea(TGAEXTENSIONAREA *ex) {
SwapShort(&ex->extension_size);
SwapShort(&ex->datetime_stamp[0]);
SwapShort(&ex->datetime_stamp[1]);
SwapShort(&ex->datetime_stamp[2]);
SwapShort(&ex->datetime_stamp[3]);
SwapShort(&ex->datetime_stamp[4]);
SwapShort(&ex->datetime_stamp[5]);
SwapShort(&ex->job_time[0]);
SwapShort(&ex->job_time[1]);
SwapShort(&ex->job_time[2]);
SwapLong (&ex->key_color);
SwapShort(&ex->pixel_aspect_ratio[0]);
SwapShort(&ex->pixel_aspect_ratio[1]);
SwapShort(&ex->gamma_value[0]);
SwapShort(&ex->gamma_value[1]);
SwapLong (&ex->color_correction_offset);
SwapLong (&ex->postage_stamp_offset);
SwapLong (&ex->scan_line_offset);
}
static void
SwapFooter(TGAFOOTER *footer) {
SwapLong(&footer->extension_offset);
SwapLong(&footer->developer_offset);
}
#endif // FREEIMAGE_BIGENDIAN
// ==========================================================
// Plugin Interface
// ==========================================================
static int s_format_id;
// ==========================================================
// Plugin Implementation
// ==========================================================
static const char * DLL_CALLCONV
Format() {
return "TARGA";
}
static const char * DLL_CALLCONV
Description() {
return "Truevision Targa";
}
static const char * DLL_CALLCONV
Extension() {
return "tga,targa";
}
static const char * DLL_CALLCONV
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
} else {
// no rle
if(has_rle) {
// flush rle packet
// include current pixel first
assert(packet_count < max_packet_size);
++packet_count;
flushPacket(line, pixel_size, packet_begin, packet, packet_count, has_rle);
// start anew on the next pixel
continue;
} else {
writeToPacket(packet, current, pixel_size);
packet += pixel_size;
}
}
// increase counter on every pixel
++packet_count;
if(packet_count == max_packet_size) {
flushPacket(line, pixel_size, packet_begin, packet, packet_count, has_rle);
}
}//for width
// write line to disk
io->write_proc(line_begin, 1, (unsigned)(line - line_begin), handle);
}//for height
free(line_begin);
free(packet_begin);
free(current);
free(next);
}
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
if ((dib == NULL) || (handle == NULL)) {
return FALSE;
}
RGBQUAD *palette = FreeImage_GetPalette(dib);
const unsigned bpp = FreeImage_GetBPP(dib);
// write the file header
TGAHEADER header;
header.id_length = 0;
header.cm_first_entry = 0;
header.is_xorigin = 0;
header.is_yorigin = 0;
header.is_width = (WORD)FreeImage_GetWidth(dib);
header.is_height = (WORD)FreeImage_GetHeight(dib);
header.is_pixel_depth = (BYTE)bpp;
header.is_image_descriptor = (bpp == 32 ? 8 : 0);
if (palette) {
header.color_map_type = 1;
header.image_type = (TARGA_SAVE_RLE & flags) ? TGA_RLECMAP : TGA_CMAP;
header.cm_length = (WORD)(1 << bpp);
if (FreeImage_IsTransparent(dib)) {
header.cm_size = 32;
} else {
header.cm_size = 24;
}
} else {
header.color_map_type = 0;
header.image_type = (TARGA_SAVE_RLE & flags) ? TGA_RLERGB : TGA_RGB;
header.cm_length = 0;
header.cm_size = 0;
}
// write the header
#ifdef FREEIMAGE_BIGENDIAN
SwapHeader(&header);
#endif
io->write_proc(&header, sizeof(header), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
SwapHeader(&header);
#endif
// write the palette
if (palette) {
if (FreeImage_IsTransparent(dib)) {
FILE_BGRA *bgra_pal = (FILE_BGRA*)malloc(header.cm_length * sizeof(FILE_BGRA));
// get the transparency table
BYTE *trns = FreeImage_GetTransparencyTable(dib);
for (unsigned i = 0; i < header.cm_length; i++) {
bgra_pal[i].b = palette[i].rgbBlue;
bgra_pal[i].g = palette[i].rgbGreen;
bgra_pal[i].r = palette[i].rgbRed;
bgra_pal[i].a = trns[i];
}
io->write_proc(bgra_pal, sizeof(FILE_BGRA), header.cm_length, handle);
free(bgra_pal);
} else {
FILE_BGR *bgr_pal = (FILE_BGR*)malloc(header.cm_length * sizeof(FILE_BGR));
for (unsigned i = 0; i < header.cm_length; i++) {
bgr_pal[i].b = palette[i].rgbBlue;
( run in 0.468 second using v1.01-cache-2.11-cpan-5623c5533a1 )