summaryrefslogtreecommitdiffstats
path: root/src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp')
m---------src/Runtime/ogl-runtime0
-rw-r--r--src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp851
2 files changed, 0 insertions, 851 deletions
diff --git a/src/Runtime/ogl-runtime b/src/Runtime/ogl-runtime
new file mode 160000
+Subproject 2025912174c4cf99270b7439ec3b021e1d089ae
diff --git a/src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp b/src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp
deleted file mode 100644
index ece4d3a3..00000000
--- a/src/Runtime/ogl-runtime/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureGIF.cpp
+++ /dev/null
@@ -1,851 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2008-2012 NVIDIA Corporation.
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt 3D Studio.
-**
-** $QT_BEGIN_LICENSE:GPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 or (at your option) any later version
-** approved by the KDE Free Qt Foundation. The licenses are as published by
-** the Free Software Foundation and appearing in the file LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-// ==========================================================
-// GIF Loader and Writer
-//
-// Design and implementation by
-// - Ryan Rubley <ryan@lostreality.org>
-// - Raphael Gaquer <raphael.gaquer@alcer.com>
-//
-// 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!
-// ==========================================================
-#ifdef _MSC_VER
-#pragma warning(disable : 4786) // identifier was truncated to 'number' characters
-#endif
-
-#include "Qt3DSRenderLoadedTextureFreeImageCompat.h"
-#include "EASTL/vector.h"
-#include "EASTL/string.h"
-// ==========================================================
-// Metadata declarations
-// ==========================================================
-
-#define GIF_DISPOSAL_UNSPECIFIED 0
-#define GIF_DISPOSAL_LEAVE 1
-#define GIF_DISPOSAL_BACKGROUND 2
-#define GIF_DISPOSAL_PREVIOUS 3
-
-// ==========================================================
-// Constant/Typedef declarations
-// ==========================================================
-
-struct GIFinfo
-{
- BOOL read;
- // only really used when reading
- size_t global_color_table_offset;
- int global_color_table_size;
- BYTE background_color;
- eastl::vector<size_t> application_extension_offsets;
- eastl::vector<size_t> comment_extension_offsets;
- eastl::vector<size_t> graphic_control_extension_offsets;
- eastl::vector<size_t> image_descriptor_offsets;
-
- GIFinfo()
- : read(0)
- , global_color_table_offset(0)
- , global_color_table_size(0)
- , background_color(0)
- {
- }
-};
-
-struct PageInfo
-{
- PageInfo(int d, int l, int t, int w, int h)
- {
- disposal_method = d;
- left = (WORD)l;
- top = (WORD)t;
- width = (WORD)w;
- height = (WORD)h;
- }
- int disposal_method;
- WORD left, top, width, height;
-};
-
-// GIF defines a max of 12 bits per code
-#define MAX_LZW_CODE 4096
-
-class StringTable
-{
-public:
- StringTable();
- ~StringTable();
- void Initialize(int minCodeSize);
- BYTE *FillInputBuffer(int len);
- void CompressStart(int bpp, int width);
- int CompressEnd(BYTE *buf); // 0-4 bytes
- bool Compress(BYTE *buf, int *len);
- bool Decompress(BYTE *buf, int *len);
- void Done(void);
-
-protected:
- bool m_done;
-
- int m_minCodeSize, m_clearCode, m_endCode, m_nextCode;
-
- int m_bpp, m_slack; // Compressor information
-
- int m_prefix; // Compressor state variable
- int m_codeSize, m_codeMask; // Compressor/Decompressor state variables
- int m_oldCode; // Decompressor state variable
- int m_partial, m_partialSize; // Compressor/Decompressor bit buffer
-
- int firstPixelPassed; // A specific flag that indicates if the first pixel
- // of the whole image had already been read
-
- eastl::string m_strings[MAX_LZW_CODE]; // This is what is really the "string table" data for the
- // Decompressor
- int *m_strmap;
-
- // input buffer
- BYTE *m_buffer;
- int m_bufferSize, m_bufferRealSize, m_bufferPos, m_bufferShift;
-
- void ClearCompressorTable(void);
- void ClearDecompressorTable(void);
-};
-
-#define GIF_PACKED_LSD_HAVEGCT 0x80
-#define GIF_PACKED_LSD_COLORRES 0x70
-#define GIF_PACKED_LSD_GCTSORTED 0x08
-#define GIF_PACKED_LSD_GCTSIZE 0x07
-#define GIF_PACKED_ID_HAVELCT 0x80
-#define GIF_PACKED_ID_INTERLACED 0x40
-#define GIF_PACKED_ID_LCTSORTED 0x20
-#define GIF_PACKED_ID_RESERVED 0x18
-#define GIF_PACKED_ID_LCTSIZE 0x07
-#define GIF_PACKED_GCE_RESERVED 0xE0
-#define GIF_PACKED_GCE_DISPOSAL 0x1C
-#define GIF_PACKED_GCE_WAITINPUT 0x02
-#define GIF_PACKED_GCE_HAVETRANS 0x01
-
-#define GIF_BLOCK_IMAGE_DESCRIPTOR 0x2C
-#define GIF_BLOCK_EXTENSION 0x21
-#define GIF_BLOCK_TRAILER 0x3B
-
-#define GIF_EXT_PLAINTEXT 0x01
-#define GIF_EXT_GRAPHIC_CONTROL 0xF9
-#define GIF_EXT_COMMENT 0xFE
-#define GIF_EXT_APPLICATION 0xFF
-
-#define GIF_INTERLACE_PASSES 4
-static int g_GifInterlaceOffset[GIF_INTERLACE_PASSES] = { 0, 4, 2, 1 };
-static int g_GifInterlaceIncrement[GIF_INTERLACE_PASSES] = { 8, 8, 4, 2 };
-
-StringTable::StringTable()
-{
- m_buffer = NULL;
- firstPixelPassed = 0; // Still no pixel read
- // Maximum number of entries in the map is MAX_LZW_CODE * 256
- // (aka 2**12 * 2**8 => a 20 bits key)
- // This Map could be optmized to only handle MAX_LZW_CODE * 2**(m_bpp)
- m_strmap = (int *)new int[1 << 20];
-}
-
-StringTable::~StringTable()
-{
- if (m_buffer != NULL) {
- delete[] m_buffer;
- }
- if (m_strmap != NULL) {
- delete[] m_strmap;
- m_strmap = NULL;
- }
-}
-
-void StringTable::Initialize(int minCodeSize)
-{
- m_done = false;
-
- m_bpp = 8;
- m_minCodeSize = minCodeSize;
- m_clearCode = 1 << m_minCodeSize;
- if (m_clearCode > MAX_LZW_CODE) {
- m_clearCode = MAX_LZW_CODE;
- }
- m_endCode = m_clearCode + 1;
-
- m_partial = 0;
- m_partialSize = 0;
-
- m_bufferSize = 0;
- ClearCompressorTable();
- ClearDecompressorTable();
-}
-
-BYTE *StringTable::FillInputBuffer(int len)
-{
- if (m_buffer == NULL) {
- m_buffer = new BYTE[len];
- m_bufferRealSize = len;
- } else if (len > m_bufferRealSize) {
- delete[] m_buffer;
- m_buffer = new BYTE[len];
- m_bufferRealSize = len;
- }
- m_bufferSize = len;
- m_bufferPos = 0;
- m_bufferShift = 8 - m_bpp;
- return m_buffer;
-}
-
-void StringTable::CompressStart(int bpp, int width)
-{
- m_bpp = bpp;
- m_slack = (8 - ((width * bpp) % 8)) % 8;
-
- m_partial |= m_clearCode << m_partialSize;
- m_partialSize += m_codeSize;
- ClearCompressorTable();
-}
-
-int StringTable::CompressEnd(BYTE *buf)
-{
- int len = 0;
-
- // output code for remaining prefix
- m_partial |= m_prefix << m_partialSize;
- m_partialSize += m_codeSize;
- while (m_partialSize >= 8) {
- *buf++ = (BYTE)m_partial;
- m_partial >>= 8;
- m_partialSize -= 8;
- len++;
- }
-
- // add the end of information code and flush the entire buffer out
- m_partial |= m_endCode << m_partialSize;
- m_partialSize += m_codeSize;
- while (m_partialSize > 0) {
- *buf++ = (BYTE)m_partial;
- m_partial >>= 8;
- m_partialSize -= 8;
- len++;
- }
-
- // most this can be is 4 bytes. 7 bits in m_partial to start + 12 for the
- // last code + 12 for the end code = 31 bits total.
- return len;
-}
-
-bool StringTable::Compress(BYTE *buf, int *len)
-{
- if (m_bufferSize == 0 || m_done) {
- return false;
- }
-
- int mask = (1 << m_bpp) - 1;
- BYTE *bufpos = buf;
- while (m_bufferPos < m_bufferSize) {
- // get the current pixel value
- char ch = (char)((m_buffer[m_bufferPos] >> m_bufferShift) & mask);
-
- // The next prefix is :
- // <the previous LZW code (on 12 bits << 8)> | <the code of the current pixel (on 8 bits)>
- int nextprefix = (((m_prefix) << 8) & 0xFFF00) + (ch & 0x000FF);
- if (firstPixelPassed) {
-
- if (m_strmap[nextprefix] > 0) {
- m_prefix = m_strmap[nextprefix];
- } else {
- m_partial |= m_prefix << m_partialSize;
- m_partialSize += m_codeSize;
- // grab full bytes for the output buffer
- while (m_partialSize >= 8 && bufpos - buf < *len) {
- *bufpos++ = (BYTE)m_partial;
- m_partial >>= 8;
- m_partialSize -= 8;
- }
-
- // add the code to the "table map"
- m_strmap[nextprefix] = m_nextCode;
-
- // increment the next highest valid code, increase the code size
- if (m_nextCode == (1 << m_codeSize)) {
- m_codeSize++;
- }
- m_nextCode++;
-
- // if we're out of codes, restart the string table
- if (m_nextCode == MAX_LZW_CODE) {
- m_partial |= m_clearCode << m_partialSize;
- m_partialSize += m_codeSize;
- ClearCompressorTable();
- }
-
- // Only keep the 8 lowest bits (prevent problems with "negative chars")
- m_prefix = ch & 0x000FF;
- }
-
- // increment to the next pixel
- if (m_bufferShift > 0
- && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack)) {
- m_bufferShift -= m_bpp;
- } else {
- m_bufferPos++;
- m_bufferShift = 8 - m_bpp;
- }
-
- // jump out here if the output buffer is full
- if (bufpos - buf == *len) {
- return true;
- }
-
- } else {
- // Specific behavior for the first pixel of the whole image
-
- firstPixelPassed = 1;
- // Only keep the 8 lowest bits (prevent problems with "negative chars")
- m_prefix = ch & 0x000FF;
-
- // increment to the next pixel
- if (m_bufferShift > 0
- && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack)) {
- m_bufferShift -= m_bpp;
- } else {
- m_bufferPos++;
- m_bufferShift = 8 - m_bpp;
- }
-
- // jump out here if the output buffer is full
- if (bufpos - buf == *len) {
- return true;
- }
- }
- }
-
- m_bufferSize = 0;
- *len = (int)(bufpos - buf);
-
- return true;
-}
-
-bool StringTable::Decompress(BYTE *buf, int *len)
-{
- if (m_bufferSize == 0 || m_done) {
- return false;
- }
-
- BYTE *bufpos = buf;
- for (; m_bufferPos < m_bufferSize; m_bufferPos++) {
- m_partial |= (int)m_buffer[m_bufferPos] << m_partialSize;
- m_partialSize += 8;
- while (m_partialSize >= m_codeSize) {
- int code = m_partial & m_codeMask;
- m_partial >>= m_codeSize;
- m_partialSize -= m_codeSize;
-
- if (code > m_nextCode || (m_nextCode == MAX_LZW_CODE && code != m_clearCode)
- || code == m_endCode) {
- m_done = true;
- *len = (int)(bufpos - buf);
- return true;
- }
- if (code == m_clearCode) {
- ClearDecompressorTable();
- continue;
- }
-
- // add new string to string table, if not the first pass since a clear code
- if (m_oldCode != MAX_LZW_CODE) {
- m_strings[m_nextCode] =
- m_strings[m_oldCode] + m_strings[code == m_nextCode ? m_oldCode : code][0];
- }
-
- if ((int)m_strings[code].size() > *len - (bufpos - buf)) {
- // out of space, stuff the code back in for next time
- m_partial <<= m_codeSize;
- m_partialSize += m_codeSize;
- m_partial |= code;
- m_bufferPos++;
- *len = (int)(bufpos - buf);
- return true;
- }
-
- // output the string into the buffer
- memcpy(bufpos, m_strings[code].data(), m_strings[code].size());
- bufpos += m_strings[code].size();
-
- // increment the next highest valid code, add a bit to the mask if we need to increase
- // the code size
- if (m_oldCode != MAX_LZW_CODE && m_nextCode < MAX_LZW_CODE) {
- if (++m_nextCode < MAX_LZW_CODE) {
- if ((m_nextCode & m_codeMask) == 0) {
- m_codeSize++;
- m_codeMask |= m_nextCode;
- }
- }
- }
-
- m_oldCode = code;
- }
- }
-
- m_bufferSize = 0;
- *len = (int)(bufpos - buf);
-
- return true;
-}
-
-void StringTable::Done(void)
-{
- m_done = true;
-}
-
-void StringTable::ClearCompressorTable(void)
-{
- if (m_strmap) {
- memset(m_strmap, 0xFF, sizeof(unsigned int) * (1 << 20));
- }
- m_nextCode = m_endCode + 1;
-
- m_prefix = 0;
- m_codeSize = m_minCodeSize + 1;
-}
-
-void StringTable::ClearDecompressorTable(void)
-{
- for (int i = 0; i < m_clearCode; i++) {
- m_strings[i].resize(1);
- m_strings[i][0] = (char)i;
- }
- m_nextCode = m_endCode + 1;
-
- m_codeSize = m_minCodeSize + 1;
- m_codeMask = (1 << m_codeSize) - 1;
- m_oldCode = MAX_LZW_CODE;
-}
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static BOOL DLL_CALLCONV Validate(FreeImageIO *io, fi_handle handle)
-{
- char buf[6];
- if (io->read_proc(buf, 6, 1, handle) < 1) {
- return FALSE;
- }
-
- BOOL bResult = FALSE;
- if (!strncmp(buf, "GIF", 3)) {
- if (buf[3] >= '0' && buf[3] <= '9' && buf[4] >= '0' && buf[4] <= '9' && buf[5] >= 'a'
- && buf[5] <= 'z') {
- bResult = TRUE;
- }
- }
-
- io->seek_proc(handle, -6, SEEK_CUR);
-
- return bResult;
-}
-
-// ----------------------------------------------------------
-
-static void *DLL_CALLCONV Open(FreeImageIO *io, fi_handle handle)
-{
- GIFinfo *info = new GIFinfo;
- if (info == NULL) {
- return NULL;
- }
- BOOL read = TRUE;
-
- // 25/02/2008 MDA: Not safe to memset GIFinfo structure with VS 2008 (safe iterators),
- // perform initialization in constructor instead.
- // memset(info, 0, sizeof(GIFinfo));
-
- info->read = read;
- try {
- // Header
- if (!Validate(io, handle)) {
- throw "Not a GIF file";
- }
- io->seek_proc(handle, 6, SEEK_CUR);
-
- // Logical Screen Descriptor
- io->seek_proc(handle, 4, SEEK_CUR);
- BYTE packed;
- if (io->read_proc(&packed, 1, 1, handle) < 1) {
- throw "EOF reading Logical Screen Descriptor";
- }
- if (io->read_proc(&info->background_color, 1, 1, handle) < 1) {
- throw "EOF reading Logical Screen Descriptor";
- }
- io->seek_proc(handle, 1, SEEK_CUR);
-
- // Global Color Table
- if (packed & GIF_PACKED_LSD_HAVEGCT) {
- info->global_color_table_offset = io->tell_proc(handle);
- info->global_color_table_size = 2 << (packed & GIF_PACKED_LSD_GCTSIZE);
- io->seek_proc(handle, 3 * info->global_color_table_size, SEEK_CUR);
- }
-
- // Scan through all the rest of the blocks, saving offsets
- size_t gce_offset = 0;
- BYTE block = 0;
- while (block != GIF_BLOCK_TRAILER) {
- if (io->read_proc(&block, 1, 1, handle) < 1) {
- throw "EOF reading blocks";
- }
- if (block == GIF_BLOCK_IMAGE_DESCRIPTOR) {
- info->image_descriptor_offsets.push_back(io->tell_proc(handle));
- // GCE may be 0, meaning no GCE preceded this ID
- info->graphic_control_extension_offsets.push_back(gce_offset);
- gce_offset = 0;
-
- io->seek_proc(handle, 8, SEEK_CUR);
- if (io->read_proc(&packed, 1, 1, handle) < 1) {
- throw "EOF reading Image Descriptor";
- }
-
- // Local Color Table
- if (packed & GIF_PACKED_ID_HAVELCT) {
- io->seek_proc(handle, 3 * (2 << (packed & GIF_PACKED_ID_LCTSIZE)), SEEK_CUR);
- }
-
- // LZW Minimum Code Size
- io->seek_proc(handle, 1, SEEK_CUR);
- } else if (block == GIF_BLOCK_EXTENSION) {
- BYTE ext;
- if (io->read_proc(&ext, 1, 1, handle) < 1) {
- throw "EOF reading extension";
- }
-
- if (ext == GIF_EXT_GRAPHIC_CONTROL) {
- // overwrite previous offset if more than one GCE found before an ID
- gce_offset = io->tell_proc(handle);
- } else if (ext == GIF_EXT_COMMENT) {
- info->comment_extension_offsets.push_back(io->tell_proc(handle));
- } else if (ext == GIF_EXT_APPLICATION) {
- info->application_extension_offsets.push_back(io->tell_proc(handle));
- }
- } else if (block == GIF_BLOCK_TRAILER) {
- continue;
- } else {
- throw "Invalid GIF block found";
- }
-
- // Data Sub-blocks
- BYTE len;
- if (io->read_proc(&len, 1, 1, handle) < 1) {
- throw "EOF reading sub-block";
- }
- while (len != 0) {
- io->seek_proc(handle, len, SEEK_CUR);
- if (io->read_proc(&len, 1, 1, handle) < 1) {
- throw "EOF reading sub-block";
- }
- }
- }
- } catch (const char *msg) {
- FreeImage_OutputMessageProc(s_format_id, msg, io);
- delete info;
- return NULL;
- }
-
- return info;
-}
-
-static FIBITMAP *DLL_CALLCONV DoLoadGIF(FreeImageIO *io, fi_handle handle, int flags, void *data)
-{
- if (data == NULL) {
- return NULL;
- }
- (void)flags;
- GIFinfo *info = (GIFinfo *)data;
-
- int page = 0;
- FIBITMAP *dib = NULL;
- try {
- bool have_transparent = false, no_local_palette = false, interlaced = false;
- int disposal_method = GIF_DISPOSAL_LEAVE, transparent_color = 0;
- WORD left, top, width, height;
- BYTE packed, b;
- WORD w;
-
- // Image Descriptor
- io->seek_proc(handle, (long)info->image_descriptor_offsets[page], SEEK_SET);
- io->read_proc(&left, 2, 1, handle);
- io->read_proc(&top, 2, 1, handle);
- io->read_proc(&width, 2, 1, handle);
- io->read_proc(&height, 2, 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&left);
- SwapShort(&top);
- SwapShort(&width);
- SwapShort(&height);
-#endif
- io->read_proc(&packed, 1, 1, handle);
- interlaced = (packed & GIF_PACKED_ID_INTERLACED) ? true : false;
- no_local_palette = (packed & GIF_PACKED_ID_HAVELCT) ? false : true;
-
- int bpp = 8;
- if (!no_local_palette) {
- int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE);
- if (size <= 2)
- bpp = 1;
- else if (size <= 16)
- bpp = 4;
- } else if (info->global_color_table_offset != 0) {
- if (info->global_color_table_size <= 2)
- bpp = 1;
- else if (info->global_color_table_size <= 16)
- bpp = 4;
- }
- dib = FreeImage_Allocate(width, height, bpp, io);
- if (dib == NULL) {
- throw "DIB allocated failed";
- }
-
- // Palette
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- if (!no_local_palette) {
- int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE);
-
- int i = 0;
- while (i < size) {
- io->read_proc(&pal[i].rgbRed, 1, 1, handle);
- io->read_proc(&pal[i].rgbGreen, 1, 1, handle);
- io->read_proc(&pal[i].rgbBlue, 1, 1, handle);
- i++;
- }
- } else if (info->global_color_table_offset != 0) {
- long pos = io->tell_proc(handle);
- io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET);
-
- int i = 0;
- while (i < info->global_color_table_size) {
- io->read_proc(&pal[i].rgbRed, 1, 1, handle);
- io->read_proc(&pal[i].rgbGreen, 1, 1, handle);
- io->read_proc(&pal[i].rgbBlue, 1, 1, handle);
- i++;
- }
-
- io->seek_proc(handle, pos, SEEK_SET);
- } else {
- // its legal to have no palette, but we're going to generate *something*
- for (int i = 0; i < 256; i++) {
- pal[i].rgbRed = (BYTE)i;
- pal[i].rgbGreen = (BYTE)i;
- pal[i].rgbBlue = (BYTE)i;
- }
- }
-
- // LZW Minimum Code Size
- io->read_proc(&b, 1, 1, handle);
- StringTable *stringtable = new StringTable;
- stringtable->Initialize(b);
-
- // Image Data Sub-blocks
- int x = 0, xpos = 0, y = 0, shift = 8 - bpp, mask = (1 << bpp) - 1, interlacepass = 0;
- BYTE *scanline = FreeImage_GetScanLine(dib, height - 1);
- BYTE buf[4096];
- io->read_proc(&b, 1, 1, handle);
- while (b) {
- io->read_proc(stringtable->FillInputBuffer(b), b, 1, handle);
- int size = sizeof(buf);
- while (stringtable->Decompress(buf, &size)) {
- for (int i = 0; i < size; i++) {
- scanline[xpos] |= (buf[i] & mask) << shift;
- if (shift > 0) {
- shift -= bpp;
- } else {
- xpos++;
- shift = 8 - bpp;
- }
- if (++x >= width) {
- if (interlaced) {
- y += g_GifInterlaceIncrement[interlacepass];
- if (y >= height && ++interlacepass < GIF_INTERLACE_PASSES) {
- y = g_GifInterlaceOffset[interlacepass];
- }
- } else {
- y++;
- }
- if (y >= height) {
- stringtable->Done();
- break;
- }
- x = xpos = 0;
- shift = 8 - bpp;
- scanline = FreeImage_GetScanLine(dib, height - y - 1);
- }
- }
- size = sizeof(buf);
- }
- io->read_proc(&b, 1, 1, handle);
- }
-
- if (page == 0) {
- QT3DSU32 idx;
-
- // Logical Screen Descriptor
- io->seek_proc(handle, 6, SEEK_SET);
- WORD logicalwidth, logicalheight;
- io->read_proc(&logicalwidth, 2, 1, handle);
- io->read_proc(&logicalheight, 2, 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&logicalwidth);
- SwapShort(&logicalheight);
-#endif
-
- // Global Color Table
- if (info->global_color_table_offset != 0) {
- RGBQUAD globalpalette[256];
- io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET);
- int i = 0;
- while (i < info->global_color_table_size) {
- io->read_proc(&globalpalette[i].rgbRed, 1, 1, handle);
- io->read_proc(&globalpalette[i].rgbGreen, 1, 1, handle);
- io->read_proc(&globalpalette[i].rgbBlue, 1, 1, handle);
- globalpalette[i].rgbReserved = 0;
- i++;
- }
- // background color
- if (info->background_color < info->global_color_table_size) {
- FreeImage_SetBackgroundColor(dib, &globalpalette[info->background_color]);
- }
- }
-
- // Application Extension
- LONG loop = 1; // If no AE with a loop count is found, the default must be 1
- for (idx = 0; idx < info->application_extension_offsets.size(); idx++) {
- io->seek_proc(handle, (long)info->application_extension_offsets[idx], SEEK_SET);
- io->read_proc(&b, 1, 1, handle);
- if (b == 11) { // All AEs start with an 11 byte sub-block to determine what type of
- // AE it is
- char buf[11];
- io->read_proc(buf, 11, 1, handle);
- if (!memcmp(buf, "NETSCAPE2.0", 11)
- || !memcmp(buf, "ANIMEXTS1.0",
- 11)) { // Not everybody recognizes ANIMEXTS1.0 but it is valid
- io->read_proc(&b, 1, 1, handle);
- if (b == 3) { // we're supposed to have a 3 byte sub-block now
- io->read_proc(&b, 1, 1,
- handle); // this should be 0x01 but isn't really important
- io->read_proc(&w, 2, 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&w);
-#endif
- loop = w;
- if (loop > 0)
- loop++;
- break;
- }
- }
- }
- }
- }
-
- // Graphic Control Extension
- if (info->graphic_control_extension_offsets[page] != 0) {
- io->seek_proc(handle, (long)(info->graphic_control_extension_offsets[page] + 1),
- SEEK_SET);
- io->read_proc(&packed, 1, 1, handle);
- io->read_proc(&w, 2, 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&w);
-#endif
- io->read_proc(&b, 1, 1, handle);
- have_transparent = (packed & GIF_PACKED_GCE_HAVETRANS) ? true : false;
- disposal_method = (packed & GIF_PACKED_GCE_DISPOSAL) >> 2;
-
- transparent_color = b;
- if (have_transparent) {
- int size = 1 << bpp;
- if (transparent_color <= size) {
- BYTE table[256];
- memset(table, 0xFF, size);
- table[transparent_color] = 0;
- FreeImage_SetTransparencyTable(dib, table, size);
- dib->m_TransparentPaletteIndex = b;
- }
- }
- }
- b = (BYTE)disposal_method;
-
- delete stringtable;
-
- } catch (const char *msg) {
- if (dib != NULL) {
- FreeImage_Unload(dib);
- }
- FreeImage_OutputMessageProc(s_format_id, msg, io);
- return NULL;
- }
-
- return dib;
-}
-
-static void DLL_CALLCONV Close(void *data)
-{
- if (data == NULL) {
- return;
- }
- GIFinfo *info = (GIFinfo *)data;
- delete info;
-}
-
-SLoadedTexture *SLoadedTexture::LoadGIF(ISeekableIOStream &inStream, bool inFlipY,
- NVFoundationBase &inFnd,
- qt3ds::render::NVRenderContextType renderContextType)
-{
- Q_UNUSED(renderContextType)
- FreeImageIO theIO(inFnd.getAllocator(), inFnd);
- void *gifData = Open(&theIO, &inStream);
- if (gifData) {
- SLoadedTexture *retval = DoLoadGIF(&theIO, &inStream, 0, gifData);
- Close(gifData);
- if (retval)
- retval->FreeImagePostProcess(inFlipY);
- return retval;
- }
- return NULL;
-}