diff options
Diffstat (limited to 'src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h')
-rw-r--r-- | src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h new file mode 100644 index 00000000..13f317bd --- /dev/null +++ b/src/Runtime/Source/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureFreeImageCompat.h @@ -0,0 +1,413 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_LOADED_TEXTURE_FREEIMAGE_COMPAT_H +#define QT3DS_RENDER_LOADED_TEXTURE_FREEIMAGE_COMPAT_H +#include "foundation/IOStreams.h" +#include "foundation/Qt3DSFoundation.h" +#include "foundation/Qt3DSBroadcastingAllocator.h" +#include "Qt3DSRenderLoadedTexture.h" +#include "EASTL/algorithm.h" +#include <stdlib.h> +#ifndef _MACOSX +#ifndef _INTEGRITYPLATFORM +#include <malloc.h> +#endif +#endif + +// We use a compatibility layer so we can easily convert freeimage code to load our texture formats +// where necessary. + +namespace qt3ds { +namespace render { + using namespace qt3ds::foundation; + + typedef int32_t BOOL; + typedef uint8_t BYTE; + typedef uint16_t WORD; + typedef uint32_t DWORD; + typedef int32_t LONG; + +#define FREEIMAGE_COLORORDER_BGR 0 +#define FREEIMAGE_COLORORDER_RGB 1 + +#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR + + typedef ISeekableIOStream *fi_handle; + + struct FreeImageIO + { + NVAllocatorCallback &m_Allocator; + NVFoundationBase &m_Foundation; + int (*read_proc)(void *data, int size, int itemSize, fi_handle handle); + void (*seek_proc)(fi_handle handle, int offset, int pos); + int (*tell_proc)(fi_handle handle); + static inline int reader(void *data, int size, int itemSize, fi_handle handle) + { + NVDataRef<QT3DSU8> theData(toDataRef((QT3DSU8 *)data, (QT3DSU32)size * itemSize)); + QT3DSU32 amount = handle->Read(theData); + return (int)amount; + } + static inline void seeker(fi_handle handle, int offset, int pos) + { + SeekPosition::Enum seekPos(SeekPosition::Begin); + /* +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_SET 0*/ + switch (pos) { + case 0: + seekPos = SeekPosition::Begin; + break; + case 1: + seekPos = SeekPosition::Current; + break; + case 2: + seekPos = SeekPosition::End; + break; + default: + QT3DS_ASSERT(false); + break; + } + handle->SetPosition(offset, seekPos); + } + static inline int teller(fi_handle handle) { return (int)handle->GetPosition(); } + FreeImageIO(NVAllocatorCallback &alloc, NVFoundationBase &fnd) + : m_Allocator(alloc) + , m_Foundation(fnd) + , read_proc(reader) + , seek_proc(seeker) + , tell_proc(teller) + { + } + }; + + typedef SLoadedTexture FIBITMAP; + inline BYTE *FreeImage_GetBits(FIBITMAP *bmp) { return (BYTE *)bmp->data; } + + inline int FreeImage_GetHeight(FIBITMAP *bmp) { return bmp->height; } + inline int FreeImage_GetWidth(FIBITMAP *bmp) { return bmp->width; } + +#define INPLACESWAP(x, y) eastl::swap(x, y) +#define MIN(x, y) NVMin(x, y) +#define MAX(x, y) NVMax(x, y) + +#define TRUE 1 +#define FALSE 0 + + typedef struct tagBITMAPINFOHEADER + { + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; + } BITMAPINFOHEADER, *PBITMAPINFOHEADER; + + typedef struct tagRGBQUAD + { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; +#else + BYTE rgbRed; + BYTE rgbGreen; + BYTE rgbBlue; +#endif // FREEIMAGE_COLORORDER + BYTE rgbReserved; + } RGBQUAD; + + typedef struct tagRGBTRIPLE + { +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR + BYTE rgbtBlue; + BYTE rgbtGreen; + BYTE rgbtRed; +#else + BYTE rgbtRed; + BYTE rgbtGreen; + BYTE rgbtBlue; +#endif // FREEIMAGE_COLORORDER + } RGBTRIPLE; + + typedef struct tagBITMAPINFO + { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[1]; + } BITMAPINFO, *PBITMAPINFO; + + typedef struct tagFILE_RGBA + { + unsigned char r, g, b, a; + } FILE_RGBA; + + typedef struct tagFILE_BGRA + { + unsigned char b, g, r, a; + } FILE_BGRA; + + typedef struct tagFILE_RGB + { + unsigned char r, g, b; + } FILE_RGB; + + typedef struct tagFILE_BGR + { + unsigned char b, g, r; + } FILE_BGR; + +// Indexes for byte arrays, masks and shifts for treating pixels as words --- +// These coincide with the order of RGBQUAD and RGBTRIPLE ------------------- + +#ifndef FREEIMAGE_BIGENDIAN +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Little Endian (x86 / MS Windows, Linux) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x00FF0000 +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x000000FF +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 16 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 0 +#define FI_RGBA_ALPHA_SHIFT 24 +#else +// Little Endian (x86 / MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x000000FF +#define FI_RGBA_GREEN_MASK 0x0000FF00 +#define FI_RGBA_BLUE_MASK 0x00FF0000 +#define FI_RGBA_ALPHA_MASK 0xFF000000 +#define FI_RGBA_RED_SHIFT 0 +#define FI_RGBA_GREEN_SHIFT 8 +#define FI_RGBA_BLUE_SHIFT 16 +#define FI_RGBA_ALPHA_SHIFT 24 +#endif // FREEIMAGE_COLORORDER +#else +#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR +// Big Endian (PPC / none) : BGR(A) order +#define FI_RGBA_RED 2 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 0 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0x0000FF00 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0xFF000000 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 8 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 24 +#define FI_RGBA_ALPHA_SHIFT 0 +#else +// Big Endian (PPC / Linux, MaxOSX) : RGB(A) order +#define FI_RGBA_RED 0 +#define FI_RGBA_GREEN 1 +#define FI_RGBA_BLUE 2 +#define FI_RGBA_ALPHA 3 +#define FI_RGBA_RED_MASK 0xFF000000 +#define FI_RGBA_GREEN_MASK 0x00FF0000 +#define FI_RGBA_BLUE_MASK 0x0000FF00 +#define FI_RGBA_ALPHA_MASK 0x000000FF +#define FI_RGBA_RED_SHIFT 24 +#define FI_RGBA_GREEN_SHIFT 16 +#define FI_RGBA_BLUE_SHIFT 8 +#define FI_RGBA_ALPHA_SHIFT 0 +#endif // FREEIMAGE_COLORORDER +#endif // FREEIMAGE_BIGENDIAN + +#define FI_RGBA_RGB_MASK (FI_RGBA_RED_MASK | FI_RGBA_GREEN_MASK | FI_RGBA_BLUE_MASK) + +// The 16bit macros only include masks and shifts, since each color element is not byte aligned + +#define FI16_555_RED_MASK 0x7C00 +#define FI16_555_GREEN_MASK 0x03E0 +#define FI16_555_BLUE_MASK 0x001F +#define FI16_555_RED_SHIFT 10 +#define FI16_555_GREEN_SHIFT 5 +#define FI16_555_BLUE_SHIFT 0 +#define FI16_565_RED_MASK 0xF800 +#define FI16_565_GREEN_MASK 0x07E0 +#define FI16_565_BLUE_MASK 0x001F +#define FI16_565_RED_SHIFT 11 +#define FI16_565_GREEN_SHIFT 5 +#define FI16_565_BLUE_SHIFT 0 + + inline unsigned char HINIBBLE(unsigned char byte) { return byte & 0xF0; } + + inline unsigned char LOWNIBBLE(unsigned char byte) { return byte & 0x0F; } + + inline int CalculateUsedBits(int bits) + { + int bit_count = 0; + unsigned bit = 1; + + for (unsigned i = 0; i < 32; i++) { + if ((bits & bit) == bit) { + bit_count++; + } + + bit <<= 1; + } + + return bit_count; + } + + inline int CalculateLine(int width, int bitdepth) { return ((width * bitdepth) + 7) / 8; } + + inline int CalculatePitch(int line) { return (line + 3) & ~3; } + + inline int CalculateUsedPaletteEntries(int bit_count) + { + if ((bit_count >= 1) && (bit_count <= 8)) + return 1 << bit_count; + + return 0; + } + + inline unsigned char *CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) + { + return (bits + (pitch * scanline)); + } + + inline void ReplaceExtension(char *result, const char *filename, const char *extension) + { + for (size_t i = strlen(filename) - 1; i > 0; --i) { + if (filename[i] == '.') { + memcpy(result, filename, i); + result[i] = '.'; + memcpy(result + i + 1, extension, strlen(extension) + 1); + return; + } + } + + memcpy(result, filename, strlen(filename)); + result[strlen(filename)] = '.'; + memcpy(result + strlen(filename) + 1, extension, strlen(extension) + 1); + } + + inline BYTE *FreeImage_GetScanLine(FIBITMAP *bmp, int height) + { + return CalculateScanLine( + (BYTE *)bmp->data, CalculatePitch(CalculateLine(bmp->width, bmp->m_BitCount)), height); + } + +#define DLL_CALLCONV + +// ignored for now. +#define FreeImage_SetDotsPerMeterX(img, dots) +#define FreeImage_SetDotsPerMeterY(img, dots) + + inline SLoadedTexture *FreeImage_Allocate(int width, int height, int bit_count, FreeImageIO *io) + { + SLoadedTexture *theTexture = QT3DS_NEW(io->m_Allocator, SLoadedTexture)(io->m_Allocator); + int pitch = CalculatePitch(CalculateLine(width, bit_count)); + QT3DSU32 dataSize = (QT3DSU32)(height * pitch); + theTexture->dataSizeInBytes = dataSize; + theTexture->data = io->m_Allocator.allocate(dataSize, "image data", __FILE__, __LINE__); + memZero(theTexture->data, dataSize); + theTexture->width = width; + theTexture->height = height; + theTexture->m_BitCount = bit_count; + // If free image asks us for a palette, we change our format at that time. + theTexture->m_ExtendedFormat = ExtendedTextureFormats::CustomRGB; + return theTexture; + } + + inline SLoadedTexture *FreeImage_Allocate(int width, int height, int bit_count, int rmask, + int gmask, int bmask, FreeImageIO *io) + { + SLoadedTexture *retval = FreeImage_Allocate(width, height, bit_count, io); + retval->m_CustomMasks[0] = rmask; + retval->m_CustomMasks[1] = gmask; + retval->m_CustomMasks[2] = bmask; + return retval; + } + + inline RGBQUAD *FreeImage_GetPalette(SLoadedTexture *texture) + { + if (texture->m_Palette == NULL) { + texture->m_ExtendedFormat = ExtendedTextureFormats::Palettized; + QT3DSU32 memory = 256 * sizeof(RGBQUAD); + if (memory) { + texture->m_Palette = + texture->m_Allocator.allocate(memory, "texture palette", __FILE__, __LINE__); + memZero(texture->m_Palette, memory); + } + } + return (RGBQUAD *)texture->m_Palette; + } + + inline void FreeImage_Unload(SLoadedTexture *texture) { texture->release(); } + inline void FreeImage_OutputMessageProc(int, const char *message, FreeImageIO *io) + { + Q_UNUSED(io); + qCCritical(INVALID_OPERATION, "Error loading image: %s", message); + } + + inline void FreeImage_SetBackgroundColor(SLoadedTexture *texture, RGBQUAD *inColor) + { + if (inColor) { + texture->m_BackgroundColor[0] = inColor->rgbRed; + texture->m_BackgroundColor[1] = inColor->rgbGreen; + texture->m_BackgroundColor[2] = inColor->rgbBlue; + } else + memSet(texture->m_BackgroundColor, 0, 3); + } + + inline void FreeImage_SetTransparencyTable(SLoadedTexture *texture, BYTE *table, int size) + { + if (texture->m_TransparencyTable) + texture->m_Allocator.deallocate(texture->m_TransparencyTable); + texture->m_TransparencyTable = NULL; + if (table && size) { + texture->m_TransparencyTable = (uint8_t *)texture->m_Allocator.allocate( + size, "texture transparency table", __FILE__, __LINE__); + memCopy(texture->m_TransparencyTable, table, size); + } + } +} +} + +using namespace qt3ds::render; + +#endif |