From 5e4c29a6b7d6cf23b6ea0d9dd22bd4abf5c89c1a Mon Sep 17 00:00:00 2001 From: John Scipione Date: Fri, 28 Feb 2014 20:23:08 -0500 Subject: [PATCH] GIFTranslator: Style fixes --- src/add-ons/translators/gif/GIFLoad.cpp | 340 +++++++++++------- src/add-ons/translators/gif/GIFLoad.h | 145 ++++---- src/add-ons/translators/gif/GIFSave.cpp | 212 ++++++----- src/add-ons/translators/gif/GIFSave.h | 112 +++--- src/add-ons/translators/gif/GIFTranslator.cpp | 230 +++++++----- src/add-ons/translators/gif/GIFTranslator.h | 43 ++- src/add-ons/translators/gif/GIFView.cpp | 118 +++--- src/add-ons/translators/gif/GIFView.h | 80 +++-- src/add-ons/translators/gif/LoadPalette.cpp | 31 +- src/add-ons/translators/gif/LoadPalette.h | 29 +- src/add-ons/translators/gif/SFHash.cpp | 161 +++++---- src/add-ons/translators/gif/SFHash.h | 40 ++- src/add-ons/translators/gif/SavePalette.cpp | 252 +++++++------ src/add-ons/translators/gif/SavePalette.h | 75 ++-- 14 files changed, 1083 insertions(+), 785 deletions(-) diff --git a/src/add-ons/translators/gif/GIFLoad.cpp b/src/add-ons/translators/gif/GIFLoad.cpp index 64e73fef5e..2bcf30d0e6 100644 --- a/src/add-ons/translators/gif/GIFLoad.cpp +++ b/src/add-ons/translators/gif/GIFLoad.cpp @@ -13,18 +13,24 @@ // //////////////////////////////////////////////////////////////////////////////// +// Additional authors: John Scipione, + + #include "GIFLoad.h" -#include -#include -#include + #include #include #include +#include +#include +#include + + extern bool debug; -GIFLoad::GIFLoad(BPositionIO *input, BPositionIO *output) +GIFLoad::GIFLoad(BPositionIO* input, BPositionIO* output) : fatalerror(false), fInput(input), @@ -39,26 +45,32 @@ GIFLoad::GIFLoad(BPositionIO *input, BPositionIO *output) fatalerror = true; return; } - - if (debug) + + if (debug) { syslog(LOG_ERR, "GIFLoad::GIFLoad() - Image dimensions are %d x %d\n", - fWidth, fHeight); - + fWidth, fHeight); + } + unsigned char c; if (fInput->Read(&c, 1) < 1) { fatalerror = true; return; } + while (c != 0x3b) { if (c == 0x2c) { if ((!ReadGIFImageHeader()) || (!ReadGIFImageData())) { - if (debug) - syslog(LOG_ERR, "GIFLoad::GIFLoad() - A fatal error occurred\n"); + if (debug) { + syslog(LOG_ERR, "GIFLoad::GIFLoad() - " + "A fatal error occurred\n"); + } + fatalerror = true; } else { - if (debug) - syslog(LOG_ERR, "GIFLoad::GIFLoad() - Found a single image and " - "leaving\n"); + if (debug) { + syslog(LOG_ERR, "GIFLoad::GIFLoad() - " + "Found a single image and leaving\n"); + } } free(fScanLine); fScanLine = NULL; @@ -96,32 +108,44 @@ GIFLoad::GIFLoad(BPositionIO *input, BPositionIO *output) return; } } + if (fInput->Read(&c, 1) < 1) { fatalerror = true; return; } } + if (debug) syslog(LOG_ERR, "GIFLoad::GIFLoad() - Done\n"); } +GIFLoad::~GIFLoad() +{ + delete fPalette; +} + + bool GIFLoad::ReadGIFHeader() { - // Standard header + // standard header unsigned char header[13]; - if (fInput->Read(header, 13) < 13) return false; + if (fInput->Read(header, 13) < 13) + return false; + fWidth = header[6] + (header[7] << 8); fHeight = header[8] + (header[9] << 8); - + fPalette = new LoadPalette(); // Global palette if (header[10] & GIF_LOCALCOLORMAP) { fPalette->size_in_bits = (header[10] & 0x07) + 1; - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFHeader() - Found %d bit global palette\n", + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFHeader() - " + "Found %d bit global palette\n", fPalette->size_in_bits); + } int s = 1 << fPalette->size_in_bits; fPalette->size = s; @@ -132,15 +156,17 @@ GIFLoad::ReadGIFHeader() fPalette->SetColor(x, gp[x * 3], gp[x * 3 + 1], gp[x * 3 + 2]); } fPalette->backgroundindex = header[11]; - } else { // Install BeOS system palette in case local palette isn't present - color_map *map = (color_map *)system_colors(); + } else { + // install BeOS system palette in case local palette isn't present + color_map* map = (color_map*)system_colors(); for (int x = 0; x < 256; x++) { - fPalette->SetColor(x, map->color_list[x].red, + fPalette->SetColor(x, map->color_list[x].red, map->color_list[x].green, map->color_list[x].blue); } fPalette->size = 256; fPalette->size_in_bits = 8; } + return true; } @@ -151,11 +177,11 @@ GIFLoad::ReadGIFLoopBlock() unsigned char length; if (fInput->Read(&length, 1) < 1) return false; fInput->Seek(length, SEEK_CUR); - + do { - if (fInput->Read(&length, 1) < 1) { + if (fInput->Read(&length, 1) < 1) return false; - } + fInput->Seek(length, SEEK_CUR); } while (length != 0); @@ -169,78 +195,93 @@ GIFLoad::ReadGIFControlBlock() unsigned char data[6]; if (fInput->Read(data, 6) < 6) return false; + if (data[1] & 0x01) { fPalette->usetransparent = true; fPalette->transparentindex = data[4]; - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFControlBlock() - Transparency active, " - "using palette index %d\n", data[4]); + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFControlBlock() - " + "Transparency active, using palette index %d\n", data[4]); + } } + return true; } -bool -GIFLoad::ReadGIFCommentBlock() +bool +GIFLoad::ReadGIFCommentBlock() { - if (debug) syslog(LOG_ERR, "GIFLoad::ReadGIFCommentBlock() - Found:\n"); + if (debug) + syslog(LOG_ERR, "GIFLoad::ReadGIFCommentBlock() - Found:\n"); + unsigned char length; char comment_data[256]; do { if (fInput->Read(&length, 1) < 1) return false; + if (fInput->Read(comment_data, length) < length) return false; + comment_data[length] = 0x00; if (debug) syslog(LOG_ERR, "%s", comment_data); } while (length != 0x00); + if (debug) syslog(LOG_ERR, "\n"); + return true; } -bool -GIFLoad::ReadGIFUnknownBlock(unsigned char c) +bool +GIFLoad::ReadGIFUnknownBlock(unsigned char c) { if (debug) syslog(LOG_ERR, "GIFLoad::ReadGIFUnknownBlock() - Found: %d\n", c); + unsigned char length; do { if (fInput->Read(&length, 1) < 1) return false; + fInput->Seek(length, SEEK_CUR); } while (length != 0x00); + return true; } -bool -GIFLoad::ReadGIFImageHeader() +bool +GIFLoad::ReadGIFImageHeader() { unsigned char data[9]; if (fInput->Read(data, 9) < 9) return false; - + int localWidth = data[4] + (data[5] << 8); int localHeight = data[6] + (data[7] << 8); if (fWidth != localWidth || fHeight != localHeight) { - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - Local dimensions do not " - "match global, setting to %d x %d\n", localWidth, localHeight); + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - " + "Local dimensions do not match global, setting to %d x %d\n", + localWidth, localHeight); + } fWidth = localWidth; fHeight = localHeight; } - - fScanLine = (uint32 *)malloc(fWidth * 4); + + fScanLine = (uint32*)malloc(fWidth * 4); if (fScanLine == NULL) { - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - Could not allocate " - "scanline\n"); + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - " + "Could not allocate scanline\n"); + } return false; } - + BRect rect(0, 0, fWidth - 1, fHeight - 1); TranslatorBitmap header; header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP); @@ -254,126 +295,137 @@ GIFLoad::ReadGIFImageHeader() if (fOutput->Write(&header, 32) < 32) return false; - // Has local palette if (data[8] & GIF_LOCALCOLORMAP) { + // has local palette fPalette->size_in_bits = (data[8] & 0x07) + 1; int s = 1 << fPalette->size_in_bits; fPalette->size = s; - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - Found %d bit local " - "palette\n", fPalette->size_in_bits); - + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - " + "Found %d bit local palette\n", fPalette->size_in_bits); + } + unsigned char lp[256 * 3]; if (fInput->Read(lp, s * 3) < s * 3) return false; - for (int x = 0; x < s; x++) { + + for (int x = 0; x < s; x++) fPalette->SetColor(x, lp[x * 3], lp[x * 3 + 1], lp[x * 3 + 2]); - } } - + fInterlaced = data[8] & GIF_INTERLACED; if (debug) { - if (fInterlaced) - syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - Image is interlaced\n"); - else - syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - Image is not " - "interlaced\n"); + if (fInterlaced) { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - " + "Image is interlaced\n"); + } else { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - " + "Image is not interlaced\n"); + } } + return true; } bool -GIFLoad::ReadGIFImageData() +GIFLoad::ReadGIFImageData() { unsigned char newEntry[4096]; - + unsigned char cs; fInput->Read(&cs, 1); if (cs == fPalette->size_in_bits) { if (!InitFrame(fPalette->size_in_bits)) return false; } else if (cs > fPalette->size_in_bits) { - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Code_size should be %d, not " - "%d, allowing it\n", fCodeSize, cs); + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - " + "Code_size should be %d, not %d, allowing it\n", + fCodeSize, cs); + } if (!InitFrame(cs)) return false; } else if (cs < fPalette->size_in_bits) { - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Code_size should be %d, not " - "%d\n", fCodeSize, cs); + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - " + "Code_size should be %d, not %d\n", fCodeSize, cs); + } return false; } - + if (debug) syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Starting LZW\n"); - + while ((fNewCode = NextCode()) != -1 && fNewCode != fEndCode) { if (fNewCode == fClearCode) { ResetTable(); fNewCode = NextCode(); fOldCode[0] = fNewCode; fOldCodeLength = 1; - if (!OutputColor(fOldCode, 1)) goto bad_end; + if (!OutputColor(fOldCode, 1)) + goto bad_end; + if (fNewCode == -1 || fNewCode == fEndCode) { - if (debug) - syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Premature fEndCode " - "or error\n"); + if (debug) { + syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - " + "Premature fEndCode or error reading fNewCode\n"); + } goto bad_end; } continue; } - - // Explicitly check for lack of clear code at start of file + + // explicitly check for lack of clear code at start of file if (fOldCodeLength == 0) { fOldCode[0] = fNewCode; fOldCodeLength = 1; if (!OutputColor(fOldCode, 1)) goto bad_end; + continue; } - - if (fTable[fNewCode] != NULL) { // Does exist in table + + if (fTable[fNewCode] != NULL) { + // exists in table + if (!OutputColor(fTable[fNewCode], fEntrySize[fNewCode])) goto bad_end; - + //memcpy(newEntry, fOldCode, fOldCodeLength); - for (unsigned int x = 0; x < fOldCodeLength; x++) { + for (unsigned int x = 0; x < fOldCodeLength; x++) newEntry[x] = fOldCode[x]; - } - + //memcpy(newEntry + fOldCodeLength, fTable[fNewCode], 1); newEntry[fOldCodeLength] = *fTable[fNewCode]; - } else { // Does not exist in table + } else { + // does not exist in table + //memcpy(newEntry, fOldCode, fOldCodeLength); - for (unsigned int x = 0; x < fOldCodeLength; x++) { + for (unsigned int x = 0; x < fOldCodeLength; x++) newEntry[x] = fOldCode[x]; - } - + //memcpy(newEntry + fOldCodeLength, fOldCode, 1); newEntry[fOldCodeLength] = *fOldCode; - + if (!OutputColor(newEntry, fOldCodeLength + 1)) goto bad_end; } fTable[fNextCode] = MemblockAllocate(fOldCodeLength + 1); //memcpy(fTable[fNextCode], newEntry, fOldCodeLength + 1); - for (unsigned int x = 0; x < fOldCodeLength + 1; x++) { + for (unsigned int x = 0; x < fOldCodeLength + 1; x++) fTable[fNextCode][x] = newEntry[x]; - } - + fEntrySize[fNextCode] = fOldCodeLength + 1; - + //memcpy(fOldCode, fTable[fNewCode], fEntrySize[fNewCode]); - for (int x = 0; x < fEntrySize[fNewCode]; x++) { + for (int x = 0; x < fEntrySize[fNewCode]; x++) fOldCode[x] = fTable[fNewCode][x]; - } - + fOldCodeLength = fEntrySize[fNewCode]; fNextCode++; - + if (fNextCode > fMaxCode && fBits != 12) { fBits++; fMaxCode = (1 << fBits) - 1; @@ -383,27 +435,36 @@ GIFLoad::ReadGIFImageData() MemblockDeleteAll(); if (fNewCode == -1) return false; + if (debug) syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Done\n"); + return true; - + bad_end: if (debug) syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Reached a bad end\n"); + MemblockDeleteAll(); return false; } -short -GIFLoad::NextCode() +short +GIFLoad::NextCode() { while (fBitCount < fBits) { if (fByteCount == 0) { - if (fInput->Read(&fByteCount, 1) < 1) return -1; - if (fByteCount == 0) return fEndCode; - if (fInput->Read(fByteBuffer + (255 - fByteCount), - fByteCount) < fByteCount) return -1; + if (fInput->Read(&fByteCount, 1) < 1) + return -1; + + if (fByteCount == 0) + return fEndCode; + + if (fInput->Read(fByteBuffer + (255 - fByteCount), fByteCount) + < fByteCount) { + return -1; + } } fBitBuffer |= (unsigned int)fByteBuffer[255 - fByteCount] << fBitCount; fByteCount--; @@ -413,17 +474,18 @@ GIFLoad::NextCode() short s = fBitBuffer & ((1 << fBits) - 1); fBitBuffer >>= fBits; fBitCount -= fBits; + return s; } -void -GIFLoad::ResetTable() +void +GIFLoad::ResetTable() { fBits = fCodeSize + 1; fNextCode = fClearCode + 2; fMaxCode = (1 << fBits) - 1; - + MemblockDeleteAll(); for (int x = 0; x < 4096; x++) { fTable[x] = NULL; @@ -436,53 +498,58 @@ GIFLoad::ResetTable() } -bool -GIFLoad::InitFrame(int size) +bool +GIFLoad::InitFrame(int size) { fCodeSize = size; if (fCodeSize == 1) fCodeSize++; + fBits = fCodeSize + 1; fClearCode = 1 << fCodeSize; fEndCode = fClearCode + 1; fNextCode = fClearCode + 2; fMaxCode = (1 << fBits) - 1; fPass = 0; + if (fInterlaced) fRow = gl_pass_starts_at[0]; - else + else fRow = 0; - + fBitCount = 0; fBitBuffer = 0; fByteCount = 0; fOldCodeLength = 0; fNewCode = 0; fScanlinePosition = 0; - + ResetTable(); return true; } -// Do 4k mallocs, keep them in a linked list, do a first fit across them -// when a new request comes along -uchar * -GIFLoad::MemblockAllocate(int size) +uchar* +GIFLoad::MemblockAllocate(int size) { + // Do 4k mallocs, keep them in a linked list, do a first fit across + // them when a new request comes along. + if (fHeadMemblock == NULL) { fHeadMemblock = new Memblock(); - uchar *value = fHeadMemblock->data; + uchar* value = fHeadMemblock->data; fHeadMemblock->offset = size; fHeadMemblock->next = NULL; + return value; } else { - Memblock *block = fHeadMemblock; - Memblock *last = NULL; + Memblock* block = fHeadMemblock; + Memblock* last = NULL; while (block != NULL) { if (4096 - block->offset > size) { - uchar *value = block->data + block->offset; + uchar* value = block->data + block->offset; block->offset += size; + return value; } last = block; @@ -490,21 +557,23 @@ GIFLoad::MemblockAllocate(int size) } block = new Memblock(); - uchar *value = block->data; + uchar* value = block->data; block->offset = size; block->next = NULL; last->next = block; + return value; } } -// Delete the linked list -void -GIFLoad::MemblockDeleteAll() +void +GIFLoad::MemblockDeleteAll() { - Memblock *block = NULL; + Memblock* block = NULL; + while (fHeadMemblock != NULL) { + // delete the linked list block = fHeadMemblock->next; delete fHeadMemblock; fHeadMemblock = block; @@ -512,8 +581,33 @@ GIFLoad::MemblockDeleteAll() } -GIFLoad::~GIFLoad() +bool +GIFLoad::OutputColor(unsigned char* string, int size) { - delete fPalette; -} + int bpr = fWidth << 2; + for (int x = 0; x < size; x++) { + fScanLine[fScanlinePosition] = fPalette->ColorForIndex(string[x]); + fScanlinePosition++; + + if (fScanlinePosition >= fWidth) { + if (fOutput->WriteAt(32 + (fRow * bpr), fScanLine, bpr) < bpr) + return false; + + fScanlinePosition = 0; + if (fInterlaced) { + fRow += gl_increment_pass_by[fPass]; + while (fRow >= fHeight) { + fPass++; + if (fPass > 3) + return true; + + fRow = gl_pass_starts_at[fPass]; + } + } else + fRow++; + } + } + + return true; +} diff --git a/src/add-ons/translators/gif/GIFLoad.h b/src/add-ons/translators/gif/GIFLoad.h index a981b3f5b3..dcd1cd2b5b 100644 --- a/src/add-ons/translators/gif/GIFLoad.h +++ b/src/add-ons/translators/gif/GIFLoad.h @@ -13,96 +13,93 @@ // //////////////////////////////////////////////////////////////////////////////// -#ifndef GIFLOAD_H -#define GIFLOAD_H +// Additional authors: John Scipione, + +#ifndef GIF_LOAD_H +#define GIF_LOAD_H + #include #include "LoadPalette.h" + #define GIF_INTERLACED 0x40 #define GIF_LOCALCOLORMAP 0x80 -class Memblock { - public: - uchar data[4096]; - int offset; - Memblock *next; +struct Memblock { + uchar data[4096]; + int offset; + Memblock* next; }; -const int gl_pass_starts_at[] = {0, 4, 2, 1, 0}; -const int gl_increment_pass_by[] = {8, 8, 4, 2, 0}; +const int gl_pass_starts_at[] = { 0, 4, 2, 1, 0 }; +const int gl_increment_pass_by[] = { 8, 8, 4, 2, 0 }; class GIFLoad { - public: - GIFLoad(BPositionIO *input, BPositionIO *output); - ~GIFLoad(); - bool fatalerror; - - private: - bool ReadGIFHeader(); - bool ReadGIFLoopBlock(); - bool ReadGIFControlBlock(); - bool ReadGIFImageHeader(); - bool ReadGIFImageData(); - bool ReadGIFCommentBlock(); - bool ReadGIFUnknownBlock(unsigned char c); - - bool InitFrame(int size); - short NextCode(); - void ResetTable(); - - uchar *MemblockAllocate(int size); - void MemblockDeleteAll(); +public: + GIFLoad(BPositionIO* input, + BPositionIO* output); + virtual ~GIFLoad(); - inline bool OutputColor(unsigned char *string, int size) { - int bpr = fWidth << 2; - - for (int x = 0; x < size; x++) { - fScanLine[fScanlinePosition] = fPalette->ColorForIndex(string[x]); - fScanlinePosition++; - - if (fScanlinePosition >= fWidth) { - if (fOutput->WriteAt(32 + (fRow * bpr), fScanLine, bpr) < bpr) return false; - fScanlinePosition = 0; - if (fInterlaced) { - fRow += gl_increment_pass_by[fPass]; - while (fRow >= fHeight) { - fPass++; - if (fPass > 3) return true; - fRow = gl_pass_starts_at[fPass]; - } - } else fRow++; - } - } - return true; - } - - BPositionIO *fInput, *fOutput; - LoadPalette *fPalette; - bool fInterlaced; - int fPass, fRow, fWidth, fHeight; - - unsigned char fOldCode[4096]; - unsigned int fOldCodeLength; - short fNewCode; - int fBits, fMaxCode, fCodeSize; - short fClearCode, fEndCode, fNextCode; - - unsigned char *fTable[4096]; - short fEntrySize[4096]; - Memblock *fHeadMemblock; - - int fBitCount; - unsigned int fBitBuffer; - unsigned char fByteCount; - unsigned char fByteBuffer[255]; + bool fatalerror; - uint32 *fScanLine; - int fScanlinePosition; +private: + bool ReadGIFHeader(); + bool ReadGIFLoopBlock(); + bool ReadGIFControlBlock(); + bool ReadGIFImageHeader(); + bool ReadGIFImageData(); + bool ReadGIFCommentBlock(); + bool ReadGIFUnknownBlock(unsigned char c); + + bool InitFrame(int size); + short NextCode(); + void ResetTable(); + + uchar* MemblockAllocate(int size); + void MemblockDeleteAll(); + + inline bool OutputColor(unsigned char* string, int size); + + BPositionIO* fInput; + BPositionIO* fOutput; + LoadPalette* fPalette; + + bool fInterlaced; + + int fPass; + int fRow; + + int fWidth; + int fHeight; + + unsigned char fOldCode[4096]; + unsigned int fOldCodeLength; + + short fNewCode; + int fBits; + int fMaxCode; + int fCodeSize; + + short fClearCode; + short fEndCode; + short fNextCode; + + unsigned char* fTable[4096]; + short fEntrySize[4096]; + Memblock* fHeadMemblock; + + int fBitCount; + unsigned int fBitBuffer; + unsigned char fByteCount; + unsigned char fByteBuffer[255]; + + uint32* fScanLine; + int fScanlinePosition; }; -#endif +#endif // GIF_LOAD_H diff --git a/src/add-ons/translators/gif/GIFSave.cpp b/src/add-ons/translators/gif/GIFSave.cpp index 04e973b543..7805bb69ba 100644 --- a/src/add-ons/translators/gif/GIFSave.cpp +++ b/src/add-ons/translators/gif/GIFSave.cpp @@ -15,12 +15,16 @@ // Additional authors: Stephan Aßmus, // Philippe Saint-Pierre, +// John Scipione, + #include "GIFSave.h" + #include #include #include + const int gs_pass_starts_at[] = {0, 4, 2, 1, 0}; const int gs_increment_pass_by[] = {8, 8, 4, 2, 0}; const int32 one_sixteenth = (int32)((1.0 / 16.0) * 32768); @@ -30,12 +34,13 @@ const int32 seven_sixteenth = (int32)((7.0 / 16.0) * 32768); extern bool debug; + class ColorCache : public HashItem { public: unsigned char index; }; -// constructor + GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, TranslatorSettings* settings) { @@ -48,7 +53,7 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, fatalerror = true; return; } - + fatalerror = false; if (fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE) == OPTIMAL_PALETTE) palette = new SavePalette(bitmap, @@ -60,23 +65,28 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, fatalerror = true; return; } - + width = bitmap->Bounds().IntegerWidth() + 1; height = bitmap->Bounds().IntegerHeight() + 1; - if (debug) - syslog(LOG_ERR, "GIFSave::GIFSave() - Image dimensions are %d by %d\n", - width, height); - + if (debug) { + syslog(LOG_ERR, "GIFSave::GIFSave() - " + "Image dimensions are %d by %d\n", width, height); + } + if (fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)) { if (debug) syslog(LOG_ERR, "GIFSave::GIFSave() - Using dithering\n"); + red_error = new int32[width + 2]; - red_error = &red_error[1]; // Allow index of -1 too + red_error = &red_error[1]; + // Allow index of -1 too green_error = new int32[width + 2]; - green_error = &green_error[1]; // Allow index of -1 too + green_error = &green_error[1]; + // Allow index of -1 too blue_error = new int32[width + 2]; - blue_error = &blue_error[1]; // Allow index of -1 too - + blue_error = &blue_error[1]; + // Allow index of -1 too + red_side_error = green_side_error = blue_side_error = 0; for (int32 x = -1; x < width + 1; x++) { red_error[x] = 0; @@ -85,7 +95,7 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, } } else if (debug) syslog(LOG_ERR, "GIFSave::GIFSave() - Not using dithering\n"); - + if (debug) { if (fSettings->SetGetBool(GIF_SETTING_INTERLACED)) syslog(LOG_ERR, "GIFSave::GIFSave() - Interlaced, "); @@ -107,21 +117,23 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, break; } } - + if (fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)) { if (fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO)) { palette->PrepareForAutoTransparency(); - if (debug) - syslog(LOG_ERR, "GIFSave::GIFSave() - Using transparent index %d\n", + if (debug) { + syslog(LOG_ERR, "GIFSave::GIFSave() - " + "Using transparent index %d\n", palette->TransparentIndex()); + } } else { palette->SetTransparentColor( (uint8)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED), (uint8)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN), (uint8)fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE)); if (debug) { - syslog(LOG_ERR, "GIFSave::GIFSave() - Found transparent color %d,%d,%d " - "at index %d\n", + syslog(LOG_ERR, "GIFSave::GIFSave() - " + "Found transparent color %d,%d,%d at index %d\n", fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED), fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN), fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE), @@ -138,22 +150,24 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, WriteGIFHeader(); if (debug) syslog(LOG_ERR, "GIFSave::GIFSave() - Wrote gif header\n"); - + hash = new SFHash(1 << 16); WriteGIFControlBlock(); if (debug) syslog(LOG_ERR, "GIFSave::GIFSave() - Wrote gif control block\n"); + WriteGIFImageHeader(); if (debug) syslog(LOG_ERR, "GIFSave::GIFSave() - Wrote gif image header\n"); + WriteGIFImageData(); if (debug) syslog(LOG_ERR, "GIFSave::GIFSave() - Wrote gif image data\n"); - + if (fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)) { - delete [] &red_error[-1]; - delete [] &green_error[-1]; - delete [] &blue_error[-1]; + delete[] &red_error[-1]; + delete[] &green_error[-1]; + delete[] &blue_error[-1]; } delete hash; @@ -162,19 +176,20 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, output->Write(&t, 1); } -// destructor + GIFSave::~GIFSave() { delete palette; fSettings->Release(); } -// WriteGIFHeader + void GIFSave::WriteGIFHeader() { // Standard header - unsigned char header[] = {'G', 'I', 'F', '8', '9', 'a', 0, 0, 0, 0, 0, 0, 0}; + unsigned char header[] + = { 'G', 'I', 'F', '8', '9', 'a', 0, 0, 0, 0, 0, 0, 0 }; header[6] = width & 0xff; header[7] = (width & 0xff00) >> 8; header[8] = height & 0xff; @@ -182,20 +197,21 @@ GIFSave::WriteGIFHeader() header[10] = 0xf0 | (palette->SizeInBits() - 1); header[11] = palette->BackgroundIndex(); output->Write(header, 13); - - // Global palette + + // global palette int size = (1 << palette->SizeInBits()) * 3; - uint8* buffer = new uint8[size]; // can't be bigger than this + uint8* buffer = new uint8[size]; + // can't be bigger than this palette->GetColors(buffer, size); output->Write(buffer, size); delete[] buffer; } -// WriteGIFControlBlock + void GIFSave::WriteGIFControlBlock() { - unsigned char b[8] = {0x21, 0xf9, 0x04, 0, 0, 0, 0, 0x00}; + unsigned char b[8] = { 0x21, 0xf9, 0x04, 0, 0, 0, 0, 0x00 }; if (palette->UseTransparent()) { b[3] = b[3] | 1; b[6] = palette->TransparentIndex(); @@ -203,14 +219,15 @@ GIFSave::WriteGIFControlBlock() output->Write(b, 8); } -// WriteGIFImageHeader -void GIFSave::WriteGIFImageHeader() + +void +GIFSave::WriteGIFImageHeader() { unsigned char header[10]; header[0] = 0x2c; header[1] = header[2] = 0; header[3] = header[4] = 0; - + header[5] = width & 0xff; header[6] = (width & 0xff00) >> 8; header[7] = height & 0xff; @@ -220,39 +237,42 @@ void GIFSave::WriteGIFImageHeader() header[9] = 0x40; else header[9] = 0x00; + output->Write(header, 10); } -// WriteGIFImageData -void GIFSave::WriteGIFImageData() + +void +GIFSave::WriteGIFImageData() { InitFrame(); - code_value = (short *)malloc(HASHSIZE * 2); - prefix_code = (short *)malloc(HASHSIZE * 2); - append_char = (unsigned char *)malloc(HASHSIZE); + code_value = (short*)malloc(HASHSIZE * 2); + prefix_code = (short*)malloc(HASHSIZE * 2); + append_char = (unsigned char*)malloc(HASHSIZE); ResetHashtable(); - + output->Write(&code_size, 1); OutputCode(clear_code, BITS); string_code = NextPixel(0); int area = height * width; - + for (int x = 1; x < area; x++) { character = NextPixel(x); int y = 0; - if ((y = CheckHashtable(string_code, character)) != -1) { + if ((y = CheckHashtable(string_code, character)) != -1) string_code = y; - } else { + else { AddToHashtable(string_code, character); OutputCode(string_code, BITS); - + if (next_code > max_code) { BITS++; if (BITS > 12) { OutputCode(clear_code, 12); BITS = code_size + 1; ResetHashtable(); - next_code = clear_code + 1; // this is different + next_code = clear_code + 1; + // this is different } max_code = (1 << BITS) - 1; } @@ -260,6 +280,7 @@ void GIFSave::WriteGIFImageData() next_code++; } } + OutputCode(string_code, BITS); OutputCode(end_code, BITS); OutputCode(0, BITS, true); @@ -270,7 +291,7 @@ void GIFSave::WriteGIFImageData() free(append_char); } -// OutputCode + void GIFSave::OutputCode(short code, int BITS, bool flush) { @@ -278,10 +299,10 @@ GIFSave::OutputCode(short code, int BITS, bool flush) bit_buffer |= (unsigned int) code << bit_count; bit_count += BITS; while (bit_count >= 8) { - byte_buffer[byte_count + 1] = (unsigned char)(bit_buffer & 0xff); - byte_count++; - bit_buffer >>= 8; - bit_count -= 8; + byte_buffer[byte_count + 1] = (unsigned char)(bit_buffer & 0xff); + byte_count++; + bit_buffer >>= 8; + bit_count -= 8; } if (byte_count >= 255) { byte_buffer[0] = 255; @@ -289,7 +310,8 @@ GIFSave::OutputCode(short code, int BITS, bool flush) if (byte_count == 256) { byte_buffer[1] = byte_buffer[256]; byte_count = 1; - } else byte_count = 0; + } else + byte_count = 0; } } else { bit_buffer |= (unsigned int) code << bit_count; @@ -307,7 +329,7 @@ GIFSave::OutputCode(short code, int BITS, bool flush) } } -// ResetHashtable + void GIFSave::ResetHashtable() { @@ -318,7 +340,7 @@ GIFSave::ResetHashtable() } } -// CheckHashtable + int GIFSave::CheckHashtable(int s, unsigned char c) { @@ -326,34 +348,40 @@ GIFSave::CheckHashtable(int s, unsigned char c) int hashindex = HASH(s, c); int nextindex; while ((nextindex = code_value[hashindex]) != -1) { - if (prefix_code[nextindex] == s && append_char[nextindex] == c) - return nextindex; - hashindex = (hashindex + HASHSTEP) % HASHSIZE; - } + if (prefix_code[nextindex] == s && append_char[nextindex] == c) + return nextindex; + hashindex = (hashindex + HASHSTEP) % HASHSIZE; + } + return -1; } -// AddToHashtable + void GIFSave::AddToHashtable(int s, unsigned char c) { - int hashindex = HASH(s, c); - while (code_value[hashindex] != -1) hashindex = (hashindex + HASHSTEP) % HASHSIZE; - code_value[hashindex] = next_code; - prefix_code[next_code] = s; - append_char[next_code] = c; + int hashindex = HASH(s, c); + while (code_value[hashindex] != -1) + hashindex = (hashindex + HASHSTEP) % HASHSIZE; + + code_value[hashindex] = next_code; + prefix_code[next_code] = s; + append_char[next_code] = c; } -// NextPixel + unsigned char GIFSave::NextPixel(int pixel) { int bpr = bitmap->BytesPerRow(); color_space cs = bitmap->ColorSpace(); bool useAlphaForTransparency = - (fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO) + (fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT_AUTO) && cs == B_RGBA32) || cs == B_RGBA32_BIG; - unsigned char r, g, b, a; + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; if (cs == B_RGB32 || cs == B_RGBA32) { b = gifbits[0]; @@ -374,7 +402,6 @@ GIFSave::NextPixel(int pixel) || r != fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED) || g != fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN) || b != fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE)) { - if (fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)) { if (pixel % width == 0) red_side_error = green_side_error = blue_side_error = 0; @@ -384,7 +411,7 @@ GIFSave::NextPixel(int pixel) r = min_c(255, max_c(0, r - red_side_error)); } } - + if (fSettings->SetGetBool(GIF_SETTING_INTERLACED)) { if (pos >= bpr) { pos = 0; @@ -393,17 +420,17 @@ GIFSave::NextPixel(int pixel) pass++; row = gs_pass_starts_at[pass]; } - gifbits = (unsigned char *)bitmap->Bits() + (bpr * row); + gifbits = (unsigned char*)bitmap->Bits() + (bpr * row); } } -/* +#if 0 unsigned int key = (r << 16) + (g << 8) + b; - ColorCache *cc = (ColorCache *)hash->GetItem(key); + ColorCache* cc = (ColorCache*)hash->GetItem(key); if (cc == NULL) { cc = new ColorCache(); cc->key = key; cc->index = palette->IndexForColor(r, g, b); - hash->AddItem((HashItem *)cc); + hash->AddItem((HashItem*)cc); } if (prefs->usedithering) { @@ -422,10 +449,13 @@ GIFSave::NextPixel(int pixel) int32 green_total_error = palette->pal[cc->index].green - g; int32 blue_total_error = palette->pal[cc->index].blue - b; - red_side_error = (red_error[x + 1] + (red_total_error * seven_sixteenth)) >> 15; - blue_side_error = (blue_error[x + 1] + (blue_total_error * seven_sixteenth)) >> 15; - green_side_error = (green_error[x + 1] + (green_total_error * seven_sixteenth)) >> 15; - + red_side_error = (red_error[x + 1] + + (red_total_error * seven_sixteenth)) >> 15; + blue_side_error = (blue_error[x + 1] + + (blue_total_error * seven_sixteenth)) >> 15; + green_side_error = (green_error[x + 1] + + (green_total_error * seven_sixteenth)) >> 15; + red_error[x - 1] += (red_total_error * three_sixteenth); green_error[x - 1] += (green_total_error * three_sixteenth); blue_error[x - 1] += (blue_total_error * three_sixteenth); @@ -438,15 +468,17 @@ GIFSave::NextPixel(int pixel) green_error[x + 1] = (green_total_error * one_sixteenth); blue_error[x + 1] = (blue_total_error * one_sixteenth); } - - return cc->index;*/ - int index = palette->IndexForColor(r, g, b, useAlphaForTransparency ? a : 255); + return cc->index; +#endif + + int index = palette->IndexForColor(r, g, b, useAlphaForTransparency + ? a : 255); if (index != palette->TransparentIndex() && fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)) { int x = pixel % width; - // Don't carry error on to next line when interlaced because + // don't carry error on to next line when interlaced because // that line won't be adjacent, hence error is meaningless if (fSettings->SetGetBool(GIF_SETTING_INTERLACED) && x == width - 1) { for (int32 y = -1; y < width + 1; y++) { @@ -460,10 +492,13 @@ GIFSave::NextPixel(int pixel) int32 green_total_error = palette->pal[index].green - g; int32 blue_total_error = palette->pal[index].blue - b; - red_side_error = (red_error[x + 1] + (red_total_error * seven_sixteenth)) >> 15; - blue_side_error = (blue_error[x + 1] + (blue_total_error * seven_sixteenth)) >> 15; - green_side_error = (green_error[x + 1] + (green_total_error * seven_sixteenth)) >> 15; - + red_side_error = (red_error[x + 1] + + (red_total_error * seven_sixteenth)) >> 15; + blue_side_error = (blue_error[x + 1] + + (blue_total_error * seven_sixteenth)) >> 15; + green_side_error = (green_error[x + 1] + + (green_total_error * seven_sixteenth)) >> 15; + red_error[x - 1] += (red_total_error * three_sixteenth); green_error[x - 1] += (green_total_error * three_sixteenth); blue_error[x - 1] += (blue_total_error * three_sixteenth); @@ -480,13 +515,14 @@ GIFSave::NextPixel(int pixel) return index; } -// InitFrame + void GIFSave::InitFrame() { code_size = palette->SizeInBits(); if (code_size == 1) code_size++; + BITS = code_size + 1; clear_code = 1 << code_size; end_code = clear_code + 1; @@ -495,13 +531,13 @@ GIFSave::InitFrame() string_code = 0; character = 0; table_size = 1 << 12; - + bit_count = 0; bit_buffer = 0; byte_count = 0; - + pass = pos = 0; row = gs_pass_starts_at[0]; - - gifbits = (unsigned char *)bitmap->Bits(); + + gifbits = (unsigned char*)bitmap->Bits(); } diff --git a/src/add-ons/translators/gif/GIFSave.h b/src/add-ons/translators/gif/GIFSave.h index 856c35bd01..f4e4bed724 100644 --- a/src/add-ons/translators/gif/GIFSave.h +++ b/src/add-ons/translators/gif/GIFSave.h @@ -13,8 +13,13 @@ // //////////////////////////////////////////////////////////////////////////////// -#ifndef GIFSAVE_H -#define GIFSAVE_H +// Additional authors: Stephan Aßmus, +// Philippe Saint-Pierre, +// John Scipione, + +#ifndef GIF_SAVE_H +#define GIF_SAVE_H + #include #include @@ -23,60 +28,77 @@ #include "GIFTranslator.h" + #define HASHSIZE 9973 #define HASHSTEP 2039 #define HASH(index, lastbyte) (((lastbyte << 8) ^ index) % HASHSIZE) + class GIFSave { - public: - GIFSave(BBitmap* bitmap, BPositionIO* output, TranslatorSettings* settings); - ~GIFSave(); +public: + GIFSave(BBitmap* bitmap, BPositionIO* output, + TranslatorSettings* settings); + virtual ~GIFSave(); - bool fatalerror; + bool fatalerror; - private: - void WriteGIFHeader(); - void WriteGIFControlBlock(); - void WriteGIFImageHeader(); - void WriteGIFImageData(); - void OutputCode(short code, int BITS, bool flush=false); +private: + void WriteGIFHeader(); + void WriteGIFControlBlock(); + void WriteGIFImageHeader(); + void WriteGIFImageData(); + void OutputCode(short code, int BITS, + bool flush = false); - unsigned char NextPixel(int pixel); - void InitFrame(); - void ResetHashtable(); - int CheckHashtable(int s, unsigned char c); - void AddToHashtable(int s, unsigned char c); - - BPositionIO *output; - BBitmap *bitmap; - SavePalette *palette; - SFHash *hash; - TranslatorSettings *fSettings; - - short *code_value, *prefix_code; - unsigned char *append_char; - int BITS, max_code; - char code_size; - short clear_code, end_code, next_code; - int string_code; - unsigned char character; - int table_size; - - int bit_count; - unsigned int bit_buffer; - int byte_count; - unsigned char byte_buffer[257]; - int pass, row, pos; + unsigned char NextPixel(int pixel); + void InitFrame(); + void ResetHashtable(); + int CheckHashtable(int s, unsigned char c); + void AddToHashtable(int s, unsigned char c); + + BPositionIO* output; + BBitmap* bitmap; + SavePalette* palette; + SFHash* hash; + TranslatorSettings* fSettings; + + short* code_value; + short* prefix_code; + + unsigned char* append_char; + int BITS; + int max_code; + char code_size; + short clear_code; + short end_code; + short next_code; + int string_code; + unsigned char character; + int table_size; + + int bit_count; + unsigned int bit_buffer; + int byte_count; + unsigned char byte_buffer[257]; + int pass; + int row; + int pos; + + unsigned char* gifbits; + + int width; + int height; - unsigned char *gifbits; - - int width, height; - // For dithering - int32 *red_error, *green_error, *blue_error; - int16 red_side_error, green_side_error, blue_side_error; + int32* red_error; + int32* green_error; + int32* blue_error; + + int16 red_side_error; + int16 green_side_error; + int16 blue_side_error; }; -#endif +#endif // GIF_SAVE_H diff --git a/src/add-ons/translators/gif/GIFTranslator.cpp b/src/add-ons/translators/gif/GIFTranslator.cpp index 91854de931..a3bc06ff81 100644 --- a/src/add-ons/translators/gif/GIFTranslator.cpp +++ b/src/add-ons/translators/gif/GIFTranslator.cpp @@ -12,12 +12,16 @@ // original author in any about box using this software. // //////////////////////////////////////////////////////////////////////////////// -// Additional authors: Stephan Aßmus, + +// Additional authors: Stephan Aßmus, +// John Scipione, #include "GIFTranslator.h" -#include "GIFView.h" -#include "GIFSave.h" -#include "GIFLoad.h" + +#include +#include +#include +#include #include #include @@ -28,13 +32,12 @@ #include #include -#include -#include -#include -#include - +#include "GIFView.h" +#include "GIFSave.h" +#include "GIFLoad.h" #include "TranslatorWindow.h" + #ifndef GIF_TYPE #define GIF_TYPE 'GIF ' #endif @@ -43,40 +46,64 @@ #define B_TRANSLATION_CONTEXT "GIFTranslator" -// This global will be externed in other files - set once here -// for the entire translator bool debug = false; + // this global will be externed in other files - set once here + // for the entire translator -bool DetermineType(BPositionIO *source, bool *is_gif); -status_t GetBitmap(BPositionIO *in, BBitmap **out); +bool DetermineType(BPositionIO* source, bool* isGif); +status_t GetBitmap(BPositionIO* in, BBitmap** out); static const translation_format sInputFormats[] = { - { GIF_TYPE, B_TRANSLATOR_BITMAP, GIF_IN_QUALITY, GIF_IN_CAPABILITY, - "image/gif", "GIF image" }, - { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, BBM_IN_QUALITY, BBM_IN_CAPABILITY, - "image/x-be-bitmap", "Be Bitmap Format (GIFTranslator)" } + { + GIF_TYPE, + B_TRANSLATOR_BITMAP, + GIF_IN_QUALITY, + GIF_IN_CAPABILITY, + "image/gif", + "GIF image" + }, + { + B_TRANSLATOR_BITMAP, + B_TRANSLATOR_BITMAP, + BBM_IN_QUALITY, + BBM_IN_CAPABILITY, + "image/x-be-bitmap", + "Be Bitmap Format (GIFTranslator)" + } }; static const translation_format sOutputFormats[] = { - { GIF_TYPE, B_TRANSLATOR_BITMAP, GIF_OUT_QUALITY, GIF_OUT_CAPABILITY, "image/gif", - "GIF image" }, - { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, BBM_OUT_QUALITY, BBM_OUT_CAPABILITY, - "image/x-be-bitmap", "Be Bitmap Format (GIFTranslator)" } + { + GIF_TYPE, + B_TRANSLATOR_BITMAP, + GIF_OUT_QUALITY, + GIF_OUT_CAPABILITY, + "image/gif", + "GIF image" + }, + { + B_TRANSLATOR_BITMAP, + B_TRANSLATOR_BITMAP, + BBM_OUT_QUALITY, + BBM_OUT_CAPABILITY, + "image/x-be-bitmap", + "Be Bitmap Format (GIFTranslator)" + } }; // Default settings for the Translator static const TranSetting sDefaultSettings[] = { - {B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false}, - {B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false}, - {GIF_SETTING_INTERLACED, TRAN_SETTING_BOOL, false}, - {GIF_SETTING_USE_TRANSPARENT, TRAN_SETTING_BOOL, false}, - {GIF_SETTING_USE_TRANSPARENT_AUTO, TRAN_SETTING_BOOL, false}, - {GIF_SETTING_USE_DITHERING, TRAN_SETTING_BOOL, false}, - {GIF_SETTING_PALETTE_MODE, TRAN_SETTING_INT32, 0}, - {GIF_SETTING_PALETTE_SIZE, TRAN_SETTING_INT32, 8}, - {GIF_SETTING_TRANSPARENT_RED, TRAN_SETTING_INT32, 0}, - {GIF_SETTING_TRANSPARENT_GREEN, TRAN_SETTING_INT32, 0}, - {GIF_SETTING_TRANSPARENT_BLUE, TRAN_SETTING_INT32, 0} + { B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false }, + { B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false }, + { GIF_SETTING_INTERLACED, TRAN_SETTING_BOOL, false }, + { GIF_SETTING_USE_TRANSPARENT, TRAN_SETTING_BOOL, false }, + { GIF_SETTING_USE_TRANSPARENT_AUTO, TRAN_SETTING_BOOL, false }, + { GIF_SETTING_USE_DITHERING, TRAN_SETTING_BOOL, false }, + { GIF_SETTING_PALETTE_MODE, TRAN_SETTING_INT32, 0 }, + { GIF_SETTING_PALETTE_SIZE, TRAN_SETTING_INT32, 8 }, + { GIF_SETTING_TRANSPARENT_RED, TRAN_SETTING_INT32, 0 }, + { GIF_SETTING_TRANSPARENT_GREEN, TRAN_SETTING_INT32, 0 }, + { GIF_SETTING_TRANSPARENT_BLUE, TRAN_SETTING_INT32, 0 } }; const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format); @@ -85,31 +112,35 @@ const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting /* Look at first few bytes in stream to determine type - throw it back - if it is not a GIF or a BBitmap that we understand */ + * if it is not a GIF or a BBitmap that we understand. + */ bool -DetermineType(BPositionIO *source, bool *is_gif) +DetermineType(BPositionIO* source, bool* isGif) { unsigned char header[7]; - *is_gif = true; + *isGif = true; if (source->Read(header, 6) != 6) return false; header[6] = 0x00; - if (strcmp((char *)header, "GIF87a") != 0 && strcmp((char *)header, - "GIF89a") != 0) { - *is_gif = false; - int32 magic = (header[0] << 24) + (header[1] << 16) + (header[2] << 8) + if (strcmp((char*)header, "GIF87a") != 0 + && strcmp((char*)header, "GIF89a") != 0) { + *isGif = false; + int32 magic = (header[0] << 24) + (header[1] << 16) + (header[2] << 8) + header[3]; if (magic != B_TRANSLATOR_BITMAP) return false; + source->Seek(5 * 4 - 2, SEEK_CUR); color_space cs; if (source->Read(&cs, 4) != 4) return false; + cs = (color_space)B_BENDIAN_TO_HOST_INT32(cs); if (cs != B_RGB32 && cs != B_RGBA32 && cs != B_RGB32_BIG - && cs != B_RGBA32_BIG) + && cs != B_RGBA32_BIG) { return false; + } } source->Seek(0, SEEK_SET); @@ -117,12 +148,10 @@ DetermineType(BPositionIO *source, bool *is_gif) } -/* Dump data from stream into a BBitmap */ status_t -GetBitmap(BPositionIO *in, BBitmap **out) +GetBitmap(BPositionIO* in, BBitmap** out) { TranslatorBitmap header; - status_t err = in->Read(&header, sizeof(header)); if (err != sizeof(header)) return B_IO_ERROR; @@ -136,15 +165,18 @@ GetBitmap(BPositionIO *in, BBitmap **out) header.colors = (color_space)B_BENDIAN_TO_HOST_INT32(header.colors); header.dataSize = B_BENDIAN_TO_HOST_INT32(header.dataSize); + // dump data from stream into a BBitmap BBitmap* bitmap = new(std::nothrow) BBitmap(header.bounds, header.colors); *out = bitmap; if (bitmap == NULL) return B_NO_MEMORY; - unsigned char *bits = (unsigned char *)bitmap->Bits(); + + unsigned char* bits = (unsigned char*)bitmap->Bits(); if (bits == NULL) { delete bitmap; return B_NO_MEMORY; } + err = in->Read(bits, header.dataSize); if (err == (status_t)header.dataSize) return B_OK; @@ -155,29 +187,31 @@ GetBitmap(BPositionIO *in, BBitmap **out) } -/* Required Identify function - may need to read entire header, not sure */ status_t GIFTranslator::DerivedIdentify(BPositionIO* inSource, const translation_format* inFormat, BMessage* ioExtension, translator_info* outInfo, uint32 outType) { - const char *debug_text = getenv("GIF_TRANSLATOR_DEBUG"); + // Required identify function - may need to read entire header, not sure + const char* debug_text = getenv("GIF_TRANSLATOR_DEBUG"); if (debug_text != NULL && atoi(debug_text) != 0) debug = true; if (outType == 0) outType = B_TRANSLATOR_BITMAP; + if (outType != GIF_TYPE && outType != B_TRANSLATOR_BITMAP) return B_NO_TRANSLATOR; - bool is_gif; - if (!DetermineType(inSource, &is_gif)) + bool isGif; + if (!DetermineType(inSource, &isGif)) return B_NO_TRANSLATOR; - if (!is_gif && inFormat != NULL && inFormat->type != B_TRANSLATOR_BITMAP) + + if (!isGif && inFormat != NULL && inFormat->type != B_TRANSLATOR_BITMAP) return B_NO_TRANSLATOR; outInfo->group = B_TRANSLATOR_BITMAP; - if (is_gif) { + if (isGif) { outInfo->type = GIF_TYPE; outInfo->quality = GIF_IN_QUALITY; outInfo->capability = GIF_IN_CAPABILITY; @@ -191,57 +225,68 @@ GIFTranslator::DerivedIdentify(BPositionIO* inSource, sizeof(outInfo->name)); strcpy(outInfo->MIME, "image/x-be-bitmap"); } + return B_OK; } /* Main required function - assumes that an incoming GIF must be translated - to a BBitmap, and vice versa - this could be improved */ + * to a BBitmap, and vice versa - this could be improved + */ status_t GIFTranslator::DerivedTranslate(BPositionIO* inSource, const translator_info* inInfo, BMessage* ioExtension, uint32 outType, BPositionIO* outDestination, int32 baseType) { const char* debug_text = getenv("GIF_TRANSLATOR_DEBUG"); - if ((debug_text != NULL) && (atoi(debug_text) != 0)) debug = true; + if (debug_text != NULL && atoi(debug_text) != 0) + debug = true; - if (outType == 0) outType = B_TRANSLATOR_BITMAP; - if (outType != GIF_TYPE && outType != B_TRANSLATOR_BITMAP) { + if (outType == 0) + outType = B_TRANSLATOR_BITMAP; + + if (outType != GIF_TYPE && outType != B_TRANSLATOR_BITMAP) return B_NO_TRANSLATOR; - } - bool is_gif; - if (!DetermineType(inSource, &is_gif)) return B_NO_TRANSLATOR; - if (!is_gif && inInfo->type != B_TRANSLATOR_BITMAP) return B_NO_TRANSLATOR; + bool isGif; + if (!DetermineType(inSource, &isGif)) + return B_NO_TRANSLATOR; + + if (!isGif && inInfo->type != B_TRANSLATOR_BITMAP) + return B_NO_TRANSLATOR; status_t err = B_OK; bigtime_t now = system_time(); - // Going from BBitmap to GIF - if (!is_gif) { - BBitmap *bitmap = NULL; + + if (!isGif) { + // BBitmap to GIF + BBitmap* bitmap = NULL; err = GetBitmap(inSource, &bitmap); if (err != B_OK) return err; - GIFSave* gs = new GIFSave(bitmap, outDestination, fSettings); - if (gs->fatalerror) { - delete gs; + + GIFSave* gitSave = new GIFSave(bitmap, outDestination, fSettings); + if (gitSave->fatalerror) { + delete gitSave; delete bitmap; return B_NO_MEMORY; } - delete gs; + delete gitSave; delete bitmap; - } else { // GIF to BBitmap - GIFLoad *gl = new GIFLoad(inSource, outDestination); - if (gl->fatalerror) { - delete gl; + } else { + // GIF to BBitmap + GIFLoad* gifLoad = new GIFLoad(inSource, outDestination); + if (gifLoad->fatalerror) { + delete gifLoad; return B_NO_MEMORY; } - delete gl; + delete gifLoad; } if (debug) { now = system_time() - now; - syslog(LOG_ERR, "Translate() - Translation took %Ld microseconds\n", now); + syslog(LOG_ERR, "Translate() - Translation took %Ld microseconds\n", + now); } return B_OK; } @@ -250,22 +295,23 @@ GIFTranslator::DerivedTranslate(BPositionIO* inSource, BTranslator* make_nth_translator(int32 n, image_id you, uint32 flags, ...) { - if (n == 0) - return new GIFTranslator(); + if (n == 0) + return new GIFTranslator(); - return NULL; + return NULL; } GIFTranslator::GIFTranslator() - : BaseTranslator(B_TRANSLATE("GIF images"), - B_TRANSLATE("GIF image translator"), - GIF_TRANSLATOR_VERSION, - sInputFormats, kNumInputFormats, - sOutputFormats, kNumOutputFormats, - "GIFTranslator_Settings", - sDefaultSettings, kNumDefaultSettings, - B_TRANSLATOR_BITMAP, B_GIF_FORMAT) + : + BaseTranslator(B_TRANSLATE("GIF images"), + B_TRANSLATE("GIF image translator"), + GIF_TRANSLATOR_VERSION, + sInputFormats, kNumInputFormats, + sOutputFormats, kNumOutputFormats, + "GIFTranslator_Settings", + sDefaultSettings, kNumDefaultSettings, + B_TRANSLATOR_BITMAP, B_GIF_FORMAT) { } @@ -276,7 +322,7 @@ GIFTranslator::~GIFTranslator() BView* -GIFTranslator::NewConfigView(TranslatorSettings *settings) +GIFTranslator::NewConfigView(TranslatorSettings* settings) { return new GIFView(settings); } @@ -285,13 +331,13 @@ GIFTranslator::NewConfigView(TranslatorSettings *settings) int main() { - BApplication app("application/x-vnd.Haiku-GIFTranslator"); - status_t result; - result = LaunchTranslatorWindow(new GIFTranslator, - B_TRANSLATE("GIF Settings"), kRectView); - if (result == B_OK) { - app.Run(); - return 0; - } else - return 1; + BApplication app("application/x-vnd.Haiku-GIFTranslator"); + status_t result = LaunchTranslatorWindow(new GIFTranslator, + B_TRANSLATE("GIF Settings"), kRectView); + if (result == B_OK) { + app.Run(); + return 0; + } + + return 1; } diff --git a/src/add-ons/translators/gif/GIFTranslator.h b/src/add-ons/translators/gif/GIFTranslator.h index 5ce0562aa1..cb7c1f22bb 100644 --- a/src/add-ons/translators/gif/GIFTranslator.h +++ b/src/add-ons/translators/gif/GIFTranslator.h @@ -13,11 +13,15 @@ // //////////////////////////////////////////////////////////////////////////////// -#ifndef GIFTRANSLATOR_H -#define GIFTRANSLATOR_H +// Additional authors: John Scipione, + +#ifndef GIF_TRANSLATOR_H +#define GIF_TRANSLATOR_H + #include "BaseTranslator.h" + #define GIF_IN_QUALITY 0.8 #define GIF_IN_CAPABILITY 0.8 #define BBM_IN_QUALITY 0.3 @@ -28,6 +32,8 @@ #define BBM_OUT_QUALITY 0.3 #define BBM_OUT_CAPABILITY 0.3 +#define GIF_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1, 5, 0) + // settings #define GIF_SETTING_INTERLACED "interlaced" @@ -41,24 +47,25 @@ #define GIF_SETTING_TRANSPARENT_BLUE "transparent blue" -#define GIF_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1,5,0) - class GIFTranslator : public BaseTranslator { - public: - GIFTranslator(); - virtual status_t DerivedIdentify(BPositionIO* inSource, - const translation_format* inFormat, BMessage* ioExtension, - translator_info* outInfo, uint32 outType); +public: + GIFTranslator(); + virtual status_t DerivedIdentify(BPositionIO* inSource, + const translation_format* inFormat, + BMessage* ioExtension, + translator_info* outInfo, uint32 outType); - virtual status_t DerivedTranslate(BPositionIO* inSource, - const translator_info* inInfo, BMessage* ioExtension, - uint32 outType, BPositionIO* outDestination, int32 baseType); - - virtual BView* NewConfigView(TranslatorSettings* settings); - - protected: - virtual ~GIFTranslator(); + virtual status_t DerivedTranslate(BPositionIO* inSource, + const translator_info* inInfo, + BMessage* ioExtension, + uint32 outType, BPositionIO* outDestination, + int32 baseType); + + virtual BView* NewConfigView(TranslatorSettings* settings); + +protected: + virtual ~GIFTranslator(); }; -#endif +#endif // GIF_TRANSLATOR_H diff --git a/src/add-ons/translators/gif/GIFView.cpp b/src/add-ons/translators/gif/GIFView.cpp index 1e7f0a5f79..11909e73e6 100644 --- a/src/add-ons/translators/gif/GIFView.cpp +++ b/src/add-ons/translators/gif/GIFView.cpp @@ -14,11 +14,11 @@ //////////////////////////////////////////////////////////////////////////////// // Additional authors: Stephan Aßmus, -// Maxime Simon, -// Philippe Saint-Pierre, +// Philippe Saint-Pierre, +// Maxime Simon, +// John Scipione, #include "GIFView.h" -#include "GIFTranslator.h" #include #include @@ -28,13 +28,14 @@ #include #include +#include "GIFTranslator.h" #include "SavePalette.h" + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "GIFView" -// constructor GIFView::GIFView(TranslatorSettings* settings) : BView("GIFView", B_WILL_DRAW), @@ -42,20 +43,23 @@ GIFView::GIFView(TranslatorSettings* settings) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - BStringView *title = new BStringView("Title", B_TRANSLATE("GIF image translator")); + BStringView* title = new BStringView("Title", + B_TRANSLATE("GIF image translator")); title->SetFont(be_bold_font); - char version_string[100]; - snprintf(version_string, sizeof(version_string), B_TRANSLATE("v%d.%d.%d %s"), - int(B_TRANSLATION_MAJOR_VERSION(GIF_TRANSLATOR_VERSION)), - int(B_TRANSLATION_MINOR_VERSION(GIF_TRANSLATOR_VERSION)), - int(B_TRANSLATION_REVISION_VERSION(GIF_TRANSLATOR_VERSION)), - __DATE__); + char version_string[100]; + snprintf(version_string, sizeof(version_string), + B_TRANSLATE("v%d.%d.%d %s"), + int(B_TRANSLATION_MAJOR_VERSION(GIF_TRANSLATOR_VERSION)), + int(B_TRANSLATION_MINOR_VERSION(GIF_TRANSLATOR_VERSION)), + int(B_TRANSLATION_REVISION_VERSION(GIF_TRANSLATOR_VERSION)), + __DATE__); - BStringView *version = new BStringView("Version", version_string); + BStringView* version = new BStringView("Version", version_string); - const char *copyrightString = "©2003 Daniel Switkin, software@switkin.com"; - BStringView *copyright = new BStringView("Copyright", copyrightString); + const char* copyrightString + = "©2003 Daniel Switkin, software@switkin.com"; + BStringView* copyright = new BStringView("Copyright", copyrightString); // menu fields (Palette & Colors) fWebSafeMI = new BMenuItem(B_TRANSLATE("Websafe"), @@ -66,7 +70,8 @@ GIFView::GIFView(TranslatorSettings* settings) new BMessage(GV_GREYSCALE), 0, 0); fOptimalMI = new BMenuItem(B_TRANSLATE("Optimal"), new BMessage(GV_OPTIMAL), 0, 0); - fPaletteM = new BPopUpMenu("PalettePopUpMenu", true, true, B_ITEMS_IN_COLUMN); + fPaletteM = new BPopUpMenu("PalettePopUpMenu", true, true, + B_ITEMS_IN_COLUMN); fPaletteM->AddItem(fWebSafeMI); fPaletteM->AddItem(fBeOSSystemMI); fPaletteM->AddItem(fGreyScaleMI); @@ -86,34 +91,37 @@ GIFView::GIFView(TranslatorSettings* settings) } fColorCount256MI = fColorCountMI[7]; - fPaletteMF = new BMenuField(B_TRANSLATE("Palette"), fPaletteM); - fColorCountMF = new BMenuField(B_TRANSLATE("Colors"), fColorCountM); + fPaletteMF = new BMenuField(B_TRANSLATE("Palette"), fPaletteM); + fColorCountMF = new BMenuField(B_TRANSLATE("Colors"), fColorCountM); - // check boxes - fUseDitheringCB = new BCheckBox(B_TRANSLATE("Use dithering"), - new BMessage(GV_USE_DITHERING)); + // check boxes + fUseDitheringCB = new BCheckBox(B_TRANSLATE("Use dithering"), + new BMessage(GV_USE_DITHERING)); - fInterlacedCB = new BCheckBox(B_TRANSLATE("Write interlaced images"), - new BMessage(GV_INTERLACED)); + fInterlacedCB = new BCheckBox(B_TRANSLATE("Write interlaced images"), + new BMessage(GV_INTERLACED)); - fUseTransparentCB = new BCheckBox(B_TRANSLATE("Write transparent images"), - new BMessage(GV_USE_TRANSPARENT)); + fUseTransparentCB = new BCheckBox(B_TRANSLATE("Write transparent images"), + new BMessage(GV_USE_TRANSPARENT)); - // radio buttons - fUseTransparentAutoRB = new BRadioButton( - B_TRANSLATE("Automatic (from alpha channel)"), - new BMessage(GV_USE_TRANSPARENT_AUTO)); + // radio buttons + fUseTransparentAutoRB = new BRadioButton( + B_TRANSLATE("Automatic (from alpha channel)"), + new BMessage(GV_USE_TRANSPARENT_AUTO)); - fUseTransparentColorRB = new BRadioButton(B_TRANSLATE("Use RGB color"), - new BMessage(GV_USE_TRANSPARENT_COLOR)); + fUseTransparentColorRB = new BRadioButton(B_TRANSLATE("Use RGB color"), + new BMessage(GV_USE_TRANSPARENT_COLOR)); - fTransparentRedTC = new BTextControl("", "0", new BMessage(GV_TRANSPARENT_RED)); - fTransparentGreenTC = new BTextControl("", "0", new BMessage(GV_TRANSPARENT_GREEN)); - fTransparentBlueTC = new BTextControl("", "0", new BMessage(GV_TRANSPARENT_BLUE)); + fTransparentRedTC = new BTextControl("", "0", + new BMessage(GV_TRANSPARENT_RED)); + fTransparentGreenTC = new BTextControl("", "0", + new BMessage(GV_TRANSPARENT_GREEN)); + fTransparentBlueTC = new BTextControl("", "0", + new BMessage(GV_TRANSPARENT_BLUE)); - BTextView *tr = fTransparentRedTC->TextView(); - BTextView *tg = fTransparentGreenTC->TextView(); - BTextView *tb = fTransparentBlueTC->TextView(); + BTextView* tr = fTransparentRedTC->TextView(); + BTextView* tg = fTransparentGreenTC->TextView(); + BTextView* tb = fTransparentBlueTC->TextView(); for (uint32 x = 0; x < 256; x++) { if (x < '0' || x > '9') { @@ -134,10 +142,10 @@ GIFView::GIFView(TranslatorSettings* settings) .AddGrid(10, 10) .Add(fPaletteMF->CreateLabelLayoutItem(), 0, 0) - .Add(fPaletteMF->CreateMenuBarLayoutItem(), 1, 0) + .Add(fPaletteMF->CreateMenuBarLayoutItem(), 1, 0) .Add(fColorCountMF->CreateLabelLayoutItem(), 0, 1) - .Add(fColorCountMF->CreateMenuBarLayoutItem(), 1, 1) + .Add(fColorCountMF->CreateMenuBarLayoutItem(), 1, 1) .End() .AddGlue() @@ -156,7 +164,8 @@ GIFView::GIFView(TranslatorSettings* settings) BFont font; GetFont(&font); - SetExplicitPreferredSize(BSize((font.Size() * 400)/12, (font.Size() * 300)/12)); + SetExplicitPreferredSize(BSize((font.Size() * 400) / 12, + (font.Size() * 300) / 12)); RestorePrefs(); } @@ -178,23 +187,26 @@ GIFView::RestorePrefs() case WEB_SAFE_PALETTE: fWebSafeMI->SetMarked(true); break; + case BEOS_SYSTEM_PALETTE: fBeOSSystemMI->SetMarked(true); break; + case GREYSCALE_PALETTE: fGreyScaleMI->SetMarked(true); fUseDitheringCB->SetEnabled(false); break; + case OPTIMAL_PALETTE: fOptimalMI->SetMarked(true); fColorCountMF->SetEnabled(true); break; + default: int32 value = WEB_SAFE_PALETTE; fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE, &value); fSettings->SaveSettings(); fWebSafeMI->SetMarked(true); - break; } if (fColorCountMF->IsEnabled() @@ -215,9 +227,10 @@ GIFView::RestorePrefs() if (fGreyScaleMI->IsMarked()) fUseDitheringCB->SetValue(false); - else + else { fUseDitheringCB->SetValue( fSettings->SetGetBool(GIF_SETTING_USE_DITHERING)); + } fUseTransparentCB->SetValue( fSettings->SetGetBool(GIF_SETTING_USE_TRANSPARENT)); fUseTransparentAutoRB->SetValue( @@ -254,7 +267,6 @@ GIFView::RestorePrefs() } -// AllAttached void GIFView::AllAttached() { @@ -273,9 +285,8 @@ GIFView::AllAttached() } -// MessageReceived void -GIFView::MessageReceived(BMessage *message) +GIFView::MessageReceived(BMessage* message) { switch (message->what) { case GV_WEB_SAFE: @@ -287,6 +298,7 @@ GIFView::MessageReceived(BMessage *message) fColorCount256MI->SetMarked(true); break; } + case GV_BEOS_SYSTEM: { int32 value = BEOS_SYSTEM_PALETTE; @@ -296,6 +308,7 @@ GIFView::MessageReceived(BMessage *message) fColorCount256MI->SetMarked(true); break; } + case GV_GREYSCALE: { int32 value = GREYSCALE_PALETTE; @@ -308,6 +321,7 @@ GIFView::MessageReceived(BMessage *message) fColorCount256MI->SetMarked(true); break; } + case GV_OPTIMAL: { int32 value = OPTIMAL_PALETTE; @@ -318,6 +332,7 @@ GIFView::MessageReceived(BMessage *message) ->SetMarked(true); break; } + case GV_SET_COLOR_COUNT: if (fColorCountMF->IsEnabled()) { int32 sizeInBits; @@ -329,18 +344,21 @@ GIFView::MessageReceived(BMessage *message) } } break; + case GV_INTERLACED: { bool value = fInterlacedCB->Value(); fSettings->SetGetBool(GIF_SETTING_INTERLACED, &value); break; } + case GV_USE_DITHERING: { bool value = fUseDitheringCB->Value(); fSettings->SetGetBool(GIF_SETTING_USE_DITHERING, &value); break; } + case GV_USE_TRANSPARENT: { bool value = fUseTransparentCB->Value(); @@ -360,6 +378,7 @@ GIFView::MessageReceived(BMessage *message) } break; } + case GV_USE_TRANSPARENT_AUTO: { bool value = true; @@ -369,6 +388,7 @@ GIFView::MessageReceived(BMessage *message) fTransparentBlueTC->SetEnabled(false); break; } + case GV_USE_TRANSPARENT_COLOR: { bool value = false; @@ -378,33 +398,37 @@ GIFView::MessageReceived(BMessage *message) fTransparentBlueTC->SetEnabled(true); break; } + case GV_TRANSPARENT_RED: { int32 value = CheckInput(fTransparentRedTC); fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_RED, &value); break; } + case GV_TRANSPARENT_GREEN: { int32 value = CheckInput(fTransparentGreenTC); fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_GREEN, &value); break; } + case GV_TRANSPARENT_BLUE: { int32 value = CheckInput(fTransparentBlueTC); fSettings->SetGetInt32(GIF_SETTING_TRANSPARENT_BLUE, &value); break; } + default: BView::MessageReceived(message); - break; } + fSettings->SaveSettings(); } -int GIFView::CheckInput(BTextControl *control) { +int GIFView::CheckInput(BTextControl* control) { int value = atoi(control->Text()); if (value < 0 || value > 255) { value = (value < 0) ? 0 : 255; @@ -412,6 +436,6 @@ int GIFView::CheckInput(BTextControl *control) { sprintf(temp, "%d", value); control->SetText(temp); } + return value; } - diff --git a/src/add-ons/translators/gif/GIFView.h b/src/add-ons/translators/gif/GIFView.h index f9172ce861..3cae1757dd 100644 --- a/src/add-ons/translators/gif/GIFView.h +++ b/src/add-ons/translators/gif/GIFView.h @@ -14,20 +14,16 @@ //////////////////////////////////////////////////////////////////////////////// // Additional authors: Stephan Aßmus, -// Philippe Saint-Pierre, 2013, +// Philippe Saint-Pierre, +// John Scipione, + +#ifndef GIF_VIEW_H +#define GIF_VIEW_H -#ifndef GIFVIEW_H -#define GIFVIEW_H #include #include "TranslatorSettings.h" -class BMenuField; -class BPopUpMenu; -class BMenuItem; -class BCheckBox; -class BRadioButton; -class BTextControl; #define GV_WEB_SAFE 'gvws' #define GV_BEOS_SYSTEM 'gvbe' @@ -46,43 +42,51 @@ class BTextControl; const BRect kRectView(110, 110, 339, 339); + +class BMenuField; +class BPopUpMenu; +class BMenuItem; +class BCheckBox; +class BRadioButton; +class BTextControl; + class GIFView : public BView { - public: - GIFView(TranslatorSettings* settings); - virtual ~GIFView(); +public: + GIFView(TranslatorSettings* settings); + virtual ~GIFView(); - virtual void MessageReceived(BMessage* message); - virtual void AllAttached(); - - private: - void RestorePrefs(); - int CheckInput(BTextControl* control); + virtual void MessageReceived(BMessage* message); + virtual void AllAttached(); - TranslatorSettings* fSettings; +private: + void RestorePrefs(); + int CheckInput(BTextControl* control); - BMenuField* fPaletteMF; - BPopUpMenu* fPaletteM; - BMenuItem* fWebSafeMI; - BMenuItem* fBeOSSystemMI; - BMenuItem* fGreyScaleMI; - BMenuItem* fOptimalMI; + TranslatorSettings* fSettings; - BMenuField* fColorCountMF; - BPopUpMenu* fColorCountM; - BMenuItem* fColorCountMI[8]; - BMenuItem* fColorCount256MI; + BMenuField* fPaletteMF; + BPopUpMenu* fPaletteM; + BMenuItem* fWebSafeMI; + BMenuItem* fBeOSSystemMI; + BMenuItem* fGreyScaleMI; + BMenuItem* fOptimalMI; - BCheckBox* fInterlacedCB; - BCheckBox* fUseTransparentCB; - BCheckBox* fUseDitheringCB; + BMenuField* fColorCountMF; + BPopUpMenu* fColorCountM; + BMenuItem* fColorCountMI[8]; + BMenuItem* fColorCount256MI; - BRadioButton* fUseTransparentAutoRB; - BRadioButton* fUseTransparentColorRB; + BCheckBox* fInterlacedCB; + BCheckBox* fUseTransparentCB; + BCheckBox* fUseDitheringCB; - BTextControl* fTransparentRedTC; - BTextControl* fTransparentGreenTC; - BTextControl* fTransparentBlueTC; + BRadioButton* fUseTransparentAutoRB; + BRadioButton* fUseTransparentColorRB; + + BTextControl* fTransparentRedTC; + BTextControl* fTransparentGreenTC; + BTextControl* fTransparentBlueTC; }; -#endif +#endif // GIF_VIEW_H diff --git a/src/add-ons/translators/gif/LoadPalette.cpp b/src/add-ons/translators/gif/LoadPalette.cpp index 549b053c5d..71f8734c14 100644 --- a/src/add-ons/translators/gif/LoadPalette.cpp +++ b/src/add-ons/translators/gif/LoadPalette.cpp @@ -13,10 +13,15 @@ // //////////////////////////////////////////////////////////////////////////////// +// Additional authors: John Scipione, + + #include "LoadPalette.h" + #include #include + LoadPalette::LoadPalette() { backgroundindex = 0; usetransparent = false; @@ -24,19 +29,27 @@ LoadPalette::LoadPalette() { size = size_in_bits = 0; } -// Never index into pal directly - this function is safe -uint32 LoadPalette::ColorForIndex(int index) { + +uint32 +LoadPalette::ColorForIndex(int index) +{ + // never index into pal directly - this function is safe if (index >= 0 && index <= size) { - if (usetransparent && index == transparentindex) return B_TRANSPARENT_MAGIC_RGBA32; - else return data[index]; - } else { + if (usetransparent && index == transparentindex) + return B_TRANSPARENT_MAGIC_RGBA32; + else + return data[index]; + } else return B_BENDIAN_TO_HOST_INT32(0x000000ff); - } } -void LoadPalette::SetColor(int index, uint8 red, uint8 green, uint8 blue) { - if (index < 0 || index > 255) return; + +void +LoadPalette::SetColor(int index, uint8 red, uint8 green, uint8 blue) +{ + if (index < 0 || index > 255) + return; + data[index] = (blue << 24) + (green << 16) + (red << 8) + 0xff; data[index] = B_BENDIAN_TO_HOST_INT32(data[index]); } - diff --git a/src/add-ons/translators/gif/LoadPalette.h b/src/add-ons/translators/gif/LoadPalette.h index d01d37482a..488f6e5f85 100644 --- a/src/add-ons/translators/gif/LoadPalette.h +++ b/src/add-ons/translators/gif/LoadPalette.h @@ -13,24 +13,31 @@ // //////////////////////////////////////////////////////////////////////////////// +// Additional authors: John Scipione, + #ifndef LOAD_PALETTE_H #define LOAD_PALETTE_H + #include + class LoadPalette { - public: - LoadPalette(); - uint32 ColorForIndex(int index); - void SetColor(int index, uint8 red, uint8 green, uint8 blue); - - int size, size_in_bits; - int backgroundindex, transparentindex; - bool usetransparent; - - private: +public: + LoadPalette(); + + uint32 ColorForIndex(int index); + void SetColor(int index, uint8 red, uint8 green, uint8 blue); + + int size; + int size_in_bits; + int backgroundindex; + int transparentindex; + bool usetransparent; + +private: uint32 data[256]; }; -#endif +#endif // LOAD_PALETTE_H diff --git a/src/add-ons/translators/gif/SFHash.cpp b/src/add-ons/translators/gif/SFHash.cpp index e2a4586cbb..0aec18afe2 100644 --- a/src/add-ons/translators/gif/SFHash.cpp +++ b/src/add-ons/translators/gif/SFHash.cpp @@ -14,98 +14,36 @@ //////////////////////////////////////////////////////////////////////////////// // Additional authors: Stephan Aßmus, +// John Scipione, + #include "SFHash.h" -#include + #include +#include + SFHash::SFHash(int size) { fatalerror = false; this->size = size; iterate_pos = iterate_depth = 0; - main_array = (HashItem **)malloc(this->size * sizeof(HashItem *)); + main_array = (HashItem**)malloc(this->size * sizeof(HashItem*)); - if (main_array == NULL) { + if (main_array == NULL) { fatalerror = true; return; } - for (int x = 0; x < this->size; x++) { + + for (int x = 0; x < this->size; x++) main_array[x] = NULL; - } } -void SFHash::AddItem(HashItem *item) { - item->next = NULL; - int pos = item->key % size; - - if (main_array[pos] == NULL) { - main_array[pos] = item; - } - else { - HashItem *temp = main_array[pos]; - while (temp->next != NULL) temp = temp->next; - temp->next = item; - } -} - -HashItem* -SFHash::GetItem(unsigned int key) -{ - int pos = key % size; - HashItem *item = main_array[pos]; - - while (item != NULL) { - if (item->key == key) return item; - item = item->next; - } - return NULL; -} - -unsigned int -SFHash::CountItems() -{ - unsigned int count = 0; - for (int x = 0; x < this->size; x++) { - HashItem *item = main_array[x]; - while (item != NULL) { - count++; - item = item->next; - } - } - return count; -} - -HashItem* -SFHash::NextItem() -{ - if (iterate_pos >= size) { - Rewind(); - return NULL; - } - HashItem *item; - while ((item = main_array[iterate_pos]) == NULL) iterate_pos++; - for (int d = 0; d < iterate_depth; d++) { - item = item->next; - } - - if (item->next != NULL) iterate_depth++; - else { - iterate_pos++; - iterate_depth = 0; - } - return item; -} - -void SFHash::Rewind() { - iterate_pos = 0; - iterate_depth = 0; -} SFHash::~SFHash() { for (int x = 0; x < size; x++) { - HashItem *item = main_array[x]; + HashItem* item = main_array[x]; while (item != NULL) { - HashItem *t = item->next; + HashItem* t = item->next; delete item; item = t; } @@ -113,3 +51,80 @@ SFHash::~SFHash() { free(main_array); } + +void +SFHash::AddItem(HashItem* item) { + item->next = NULL; + int pos = item->key % size; + + if (main_array[pos] == NULL) + main_array[pos] = item; + else { + HashItem* temp = main_array[pos]; + while (temp->next != NULL) temp = temp->next; + temp->next = item; + } +} + + +HashItem* +SFHash::GetItem(unsigned int key) +{ + int pos = key % size; + HashItem* item = main_array[pos]; + + while (item != NULL) { + if (item->key == key) return item; + item = item->next; + } + + return NULL; +} + + +unsigned int +SFHash::CountItems() +{ + unsigned int count = 0; + for (int x = 0; x < this->size; x++) { + HashItem* item = main_array[x]; + while (item != NULL) { + count++; + item = item->next; + } + } + + return count; +} + + +HashItem* +SFHash::NextItem() +{ + if (iterate_pos >= size) { + Rewind(); + return NULL; + } + HashItem* item; + while ((item = main_array[iterate_pos]) == NULL) + iterate_pos++; + + for (int d = 0; d < iterate_depth; d++) + item = item->next; + + if (item->next != NULL) + iterate_depth++; + else { + iterate_pos++; + iterate_depth = 0; + } + + return item; +} + + +void +SFHash::Rewind() { + iterate_pos = 0; + iterate_depth = 0; +} diff --git a/src/add-ons/translators/gif/SFHash.h b/src/add-ons/translators/gif/SFHash.h index 4bd47e9256..1d92a518c2 100644 --- a/src/add-ons/translators/gif/SFHash.h +++ b/src/add-ons/translators/gif/SFHash.h @@ -14,35 +14,41 @@ //////////////////////////////////////////////////////////////////////////////// // Additional authors: Stephan Aßmus, +// John Scipione, #ifndef SFHASH_H #define SFHASH_H + class HashItem { friend class SFHash; - public: - unsigned int key; - private: - HashItem *next; +public: + unsigned int key; +private: + HashItem* next; }; + class SFHash { - public: - SFHash(int size = 4096); - ~SFHash(); +public: + SFHash(int size = 4096); + virtual ~SFHash(); - void AddItem(HashItem *item); - HashItem* GetItem(unsigned int key); - unsigned int CountItems(); - HashItem* NextItem(); - void Rewind(); + void AddItem(HashItem* item); + HashItem* GetItem(unsigned int key); + unsigned int CountItems(); + HashItem* NextItem(); + void Rewind(); - bool fatalerror; + bool fatalerror; - private: - int size, iterate_pos, iterate_depth; - HashItem **main_array; +private: + int size; + int iterate_pos; + int iterate_depth; + + HashItem** main_array; }; -#endif +#endif // SFHASH_H diff --git a/src/add-ons/translators/gif/SavePalette.cpp b/src/add-ons/translators/gif/SavePalette.cpp index 7f8d66d493..54fc594aad 100644 --- a/src/add-ons/translators/gif/SavePalette.cpp +++ b/src/add-ons/translators/gif/SavePalette.cpp @@ -14,19 +14,25 @@ //////////////////////////////////////////////////////////////////////////////// // Additional authors: Stephan Aßmus, +// John Scipione, + + +#include "SavePalette.h" + +#include +#include +#include #include -#include "SavePalette.h" #include -#include -#include -#include + using std::nothrow; extern bool debug; + // "web safe palette" const rgb_color wsp[256] = { {0xff, 0xff, 0xff, 0xff}, {0xff, 0xff, 0xcc, 0xff}, @@ -159,40 +165,43 @@ const rgb_color wsp[256] = { {0x00, 0x00, 0x00, 0xff}, {0x00, 0x00, 0x00, 0xff} }; -class ColorItem : public HashItem { - public: - ColorItem(unsigned int k, unsigned int c, - uint8 r, uint8 g, uint8 b) - : count(c), - red(r), - green(g), - blue(b) - { - key = k; - } - unsigned int count; - uint8 red; - uint8 green; - uint8 blue; + +struct ColorItem : public HashItem { + ColorItem(unsigned int k, unsigned int c, + uint8 r, uint8 g, uint8 b) + : + count(c), + red(r), + green(g), + blue(b) + { + key = k; + } + + unsigned int count; + uint8 red; + uint8 green; + uint8 blue; }; -// constructor + SavePalette::SavePalette(int mode) - : pal(new(nothrow) rgb_color[256]), - fSize(0), - fSizeInBits(8), - fMode(mode), - fTransparentMode(NO_TRANSPARENCY), - fTransparentIndex(-1), - fBackgroundIndex(0), - fFatalError(pal == NULL) + : + pal(new(nothrow) rgb_color[256]), + fSize(0), + fSizeInBits(8), + fMode(mode), + fTransparentMode(NO_TRANSPARENCY), + fTransparentIndex(-1), + fBackgroundIndex(0), + fFatalError(pal == NULL) { if (IsValid()) { if (fMode == WEB_SAFE_PALETTE) { memcpy(pal, wsp, sizeof(rgb_color) * 256); fSize = 216; } else if (fMode == BEOS_SYSTEM_PALETTE) { - color_map *map = (color_map *)system_colors(); + color_map* map = (color_map*)system_colors(); memcpy(pal, map->color_list, sizeof(rgb_color) * 256); fSize = 256; } else if (fMode == GREYSCALE_PALETTE) { @@ -205,17 +214,18 @@ SavePalette::SavePalette(int mode) } } -// make_key + static int make_key(uint8 r, uint8 g, uint8 b, uint8 bits) { r = r >> (8 - bits); g = g >> (8 - bits); b = b >> (8 - bits); + return (r << (bits * 2)) | (g << bits) | b; } -// touch_color_item + static bool touch_color_item(SFHash& hash, unsigned int key, uint8 r, uint8 g, uint8 b) { @@ -227,27 +237,30 @@ touch_color_item(SFHash& hash, unsigned int key, uint8 r, uint8 g, uint8 b) printf("Out of memory in touch_color_item()\n"); return false; } - hash.AddItem((HashItem *)ci); + hash.AddItem((HashItem*)ci); } else { ci->count++; +#if 0 // use brightest color -/* ci->red = max_c(ci->red, r); + ci->red = max_c(ci->red, r); ci->green = max_c(ci->green, g); - ci->blue = max_c(ci->blue, b);*/ + ci->blue = max_c(ci->blue, b); +#endif } return true; } -// constructor -SavePalette::SavePalette(BBitmap *bitmap, int32 maxSizeInBits) - : pal(new(nothrow) rgb_color[256]), - fSize(0), - fSizeInBits(0), - fMode(OPTIMAL_PALETTE), - fTransparentMode(NO_TRANSPARENCY), - fTransparentIndex(-1), - fBackgroundIndex(0), - fFatalError(pal == NULL) + +SavePalette::SavePalette(BBitmap* bitmap, int32 maxSizeInBits) + : + pal(new(nothrow) rgb_color[256]), + fSize(0), + fSizeInBits(0), + fMode(OPTIMAL_PALETTE), + fTransparentMode(NO_TRANSPARENCY), + fTransparentIndex(-1), + fBackgroundIndex(0), + fFatalError(pal == NULL) { if (!IsValid()) return; @@ -255,31 +268,35 @@ SavePalette::SavePalette(BBitmap *bitmap, int32 maxSizeInBits) SFHash hash(1 << 16); if (hash.fatalerror) { if (debug) - printf("Out of memory in SavePalette(BBitmap *)\n"); + printf("Out of memory in SavePalette(BBitmap*)\n"); fFatalError = true; return; } // reject unsupported color spaces // TODO: B_CMAP8 and B_GRAY8 should be really easy to support as well!! - color_space cs = bitmap->ColorSpace(); - if (cs != B_RGB32 && cs != B_RGBA32 && cs != B_RGB32_BIG && cs != B_RGBA32_BIG) { - if (debug) { - printf("Wrong color space given in SavePalette(BBitmap):\n"); - printf("%d %d %d %d or 0x%x\n", (cs & 0xff000000) >> 24, (cs & 0xff0000) >> 16, - (cs & 0xff00) >> 8, cs & 0xff, cs); - } - fFatalError = true; - return; - } - + color_space cs = bitmap->ColorSpace(); + if (cs != B_RGB32 && cs != B_RGBA32 && cs != B_RGB32_BIG + && cs != B_RGBA32_BIG) { + if (debug) { + printf("Wrong color space given in SavePalette(BBitmap):\n"); + printf("%d %d %d %d or 0x%x\n", + (cs & 0xff000000) >> 24, (cs & 0xff0000) >> 16, + (cs & 0xff00) >> 8, cs & 0xff, cs); + } + fFatalError = true; + return; + } + BRect rect = bitmap->Bounds(); uint32 height = rect.IntegerHeight() + 1; uint32 width = rect.IntegerWidth() + 1; uint8* bits = (uint8*)bitmap->Bits(); uint32 bpr = bitmap->BytesPerRow(); - uint8 r, g, b; + uint8 r; + uint8 g; + uint8 b; uint8 useBits = 3 + maxSizeInBits / 2; if (cs == B_RGB32 || cs == B_RGBA32) { for (uint32 y = 0; y < height; y++) { @@ -292,13 +309,15 @@ SavePalette::SavePalette(BBitmap *bitmap, int32 maxSizeInBits) uint32 key = make_key(r, g, b, useBits); if (!touch_color_item(hash, key, r, g, b)) { - if (debug) printf("Out of memory in SavePalette(BBitmap *)\n"); + if (debug) + printf("Out of memory in SavePalette(BBitmap*)\n"); + fFatalError = true; - return; - } - } - bits += bpr; - } + return; + } + } + bits += bpr; + } } else if ((cs == B_RGB32_BIG || cs == B_RGBA32_BIG)) { for (uint32 y = 0; y < height; y++) { uint8* handle = bits; @@ -310,66 +329,68 @@ SavePalette::SavePalette(BBitmap *bitmap, int32 maxSizeInBits) uint32 key = make_key(r, g, b, useBits); if (!touch_color_item(hash, key, r, g, b)) { - if (debug) printf("Out of memory in SavePalette(BBitmap *)\n"); + if (debug) + printf("Out of memory in SavePalette(BBitmap*)\n"); fFatalError = true; - return; - } - } - bits += bpr; - } + return; + } + } + bits += bpr; + } } - + int unique_colors = hash.CountItems(); - while (((1 << fSizeInBits) < unique_colors) && (fSizeInBits < maxSizeInBits)) + while (((1 << fSizeInBits) < unique_colors) + && (fSizeInBits < maxSizeInBits)) { fSizeInBits++; + } fSize = 1 << fSizeInBits; - ColorItem **topcolors = (ColorItem **)malloc(fSize * sizeof(ColorItem *)); - if (topcolors == NULL) { - if (debug) printf("Out of memory in SavePalette(BBitmap *)\n"); - fFatalError = true; - return; - } - ColorItem *dummy = new ColorItem(0, 0, 0, 0, 0); - for (int i = 0; i < fSize; i++) - topcolors[i] = dummy; + ColorItem** topcolors = (ColorItem**)malloc(fSize * sizeof(ColorItem*)); + if (topcolors == NULL) { + if (debug) printf("Out of memory in SavePalette(BBitmap*)\n"); + fFatalError = true; + return; + } + ColorItem* dummy = new ColorItem(0, 0, 0, 0, 0); + for (int i = 0; i < fSize; i++) + topcolors[i] = dummy; - for (int i = 0; i < unique_colors; i++) { - ColorItem *ci = (ColorItem *)hash.NextItem(); - for (int j = 0; j < fSize; j++) { - if (ci->count > topcolors[j]->count) { - for (int k = fSize - 1; k > j; k--) { - topcolors[k] = topcolors[k - 1]; - } - topcolors[j] = ci; - break; - } - } - } - - for (int i = 0; i < fSize; i++) { - pal[i].red = topcolors[i]->red; - pal[i].green = topcolors[i]->green; - pal[i].blue = topcolors[i]->blue; - pal[i].alpha = 0xff; - } - - delete dummy; - free(topcolors); + for (int i = 0; i < unique_colors; i++) { + ColorItem* ci = (ColorItem*)hash.NextItem(); + for (int j = 0; j < fSize; j++) { + if (ci->count > topcolors[j]->count) { + for (int k = fSize - 1; k > j; k--) { + topcolors[k] = topcolors[k - 1]; + } + topcolors[j] = ci; + break; + } + } + } + + for (int i = 0; i < fSize; i++) { + pal[i].red = topcolors[i]->red; + pal[i].green = topcolors[i]->green; + pal[i].blue = topcolors[i]->blue; + pal[i].alpha = 0xff; + } + + delete dummy; + free(topcolors); } -// destructor + SavePalette::~SavePalette() { delete[] pal; } -// IndexForColor -// -// standard mapping services once a palette is loaded + uint8 SavePalette::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) { + // standard mapping services once a palette is loaded if (fTransparentMode > NO_TRANSPARENCY && alpha < 128) return fTransparentIndex; @@ -378,13 +399,16 @@ SavePalette::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) if (fMode == GREYSCALE_PALETTE) { index = (308 * red + 600 * green + 116 * blue) / 1024; // avoid transparent index - if (fTransparentMode == AUTO_TRANSPARENCY && index == 1 && fTransparentIndex == 1) + if (fTransparentMode == AUTO_TRANSPARENCY && index == 1 + && fTransparentIndex == 1) { index = 0; + } } else { int closestDistance = 255 * 255 * 3; if (fTransparentMode == AUTO_TRANSPARENCY) { - for (int i = 0; i < fTransparentIndex && closestDistance != 0; i++) { + for (int i = 0; i < fTransparentIndex && closestDistance != 0; + i++) { int rd = (int)red - (int)pal[i].red; int gd = (int)green - (int)pal[i].green; int bd = (int)blue - (int)pal[i].blue; @@ -394,7 +418,8 @@ SavePalette::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) index = i; } } - for (int i = fTransparentIndex + 1; i < fSize && closestDistance != 0; i++) { + for (int i = fTransparentIndex + 1; + i < fSize && closestDistance != 0; i++) { int rd = (int)red - (int)pal[i].red; int gd = (int)green - (int)pal[i].green; int bd = (int)blue - (int)pal[i].blue; @@ -417,10 +442,11 @@ SavePalette::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) } } } + return index; } -// SetTransparentIndex + void SavePalette::PrepareForAutoTransparency() { @@ -448,7 +474,7 @@ SavePalette::PrepareForAutoTransparency() } } -// SetTransparentColor + void SavePalette::SetTransparentColor(uint8 red, uint8 green, uint8 blue) { @@ -460,7 +486,7 @@ SavePalette::SetTransparentColor(uint8 red, uint8 green, uint8 blue) if (pal[i].red == red && pal[i].green == green && pal[i].blue == blue) { - + fTransparentIndex = i; found = true; @@ -489,7 +515,7 @@ SavePalette::SetTransparentColor(uint8 red, uint8 green, uint8 blue) } } -// GetColors + void SavePalette::GetColors(uint8* buffer, int size) const { diff --git a/src/add-ons/translators/gif/SavePalette.h b/src/add-ons/translators/gif/SavePalette.h index 90cf8e7d57..61155ea511 100644 --- a/src/add-ons/translators/gif/SavePalette.h +++ b/src/add-ons/translators/gif/SavePalette.h @@ -13,12 +13,14 @@ // //////////////////////////////////////////////////////////////////////////////// +// Additional authors: John Scipione, + #ifndef SAVE_PALETTE_H #define SAVE_PALETTE_H + #include "SFHash.h" #include -class BBitmap; enum { WEB_SAFE_PALETTE = 0, @@ -33,51 +35,52 @@ enum { COLOR_KEY_TRANSPARENCY }; + +class BBitmap; + class SavePalette { - public: - SavePalette(int mode); - SavePalette(BBitmap *bitmap, - int32 maxSizeInBits = 8); - virtual ~SavePalette(); +public: + SavePalette(int mode); + SavePalette(BBitmap* bitmap, + int32 maxSizeInBits = 8); + virtual ~SavePalette(); - inline bool IsValid() const - { return !fFatalError; } + inline bool IsValid() const + { return !fFatalError; } - uint8 IndexForColor(uint8 red, uint8 green, - uint8 blue, uint8 alpha = 255); - inline uint8 IndexForColor(const rgb_color& color); + uint8 IndexForColor(uint8 red, uint8 green, + uint8 blue, uint8 alpha = 255); + inline uint8 IndexForColor(const rgb_color& color); - inline bool UseTransparent() const - { return fTransparentMode > NO_TRANSPARENCY; } + inline bool UseTransparent() const + { return fTransparentMode > NO_TRANSPARENCY; } - void PrepareForAutoTransparency(); - inline int TransparentIndex() const - { return fTransparentIndex; } - void SetTransparentColor(uint8 red, - uint8 green, - uint8 blue); + void PrepareForAutoTransparency(); + inline int TransparentIndex() const + { return fTransparentIndex; } + void SetTransparentColor(uint8 red, + uint8 green, uint8 blue); - inline int SizeInBits() const - { return fSizeInBits; } + inline int SizeInBits() const { return fSizeInBits; } - inline int BackgroundIndex() const - { return fBackgroundIndex; } + inline int BackgroundIndex() const + { return fBackgroundIndex; } - void GetColors(uint8* buffer, int size) const; + void GetColors(uint8* buffer, int size) const; - rgb_color* pal; + rgb_color* pal; - private: - int fSize; - int fSizeInBits; - int fMode; - uint32 fTransparentMode; - int fTransparentIndex; - int fBackgroundIndex; - bool fFatalError; +private: + int fSize; + int fSizeInBits; + int fMode; + uint32 fTransparentMode; + int fTransparentIndex; + int fBackgroundIndex; + bool fFatalError; }; -// IndexForColor + inline uint8 SavePalette::IndexForColor(const rgb_color& color) { @@ -85,6 +88,4 @@ SavePalette::IndexForColor(const rgb_color& color) } -#endif - - +#endif // SAVE_PALETTE_H