summaryrefslogtreecommitdiff
path: root/ZAPDTR/ZAPD/ImageBackend.cpp
diff options
context:
space:
mode:
authorlouist103 <35883445+louist103@users.noreply.github.com>2023-10-17 00:32:42 -0400
committerGitHub <noreply@github.com>2023-10-17 00:32:42 -0400
commit4a70fea67f6c1fc5b2765a5d86df51a12d06b954 (patch)
tree8db63aa641021b8d3c8521114c6f2a083e962c91 /ZAPDTR/ZAPD/ImageBackend.cpp
parentfe90ad0268efbe78fbd73b5567a35563339aa94f (diff)
Move ZAPDTR and OTRExporter to sub modules (#3298)
Diffstat (limited to 'ZAPDTR/ZAPD/ImageBackend.cpp')
m---------ZAPDTR0
-rw-r--r--ZAPDTR/ZAPD/ImageBackend.cpp506
2 files changed, 0 insertions, 506 deletions
diff --git a/ZAPDTR b/ZAPDTR
new file mode 160000
+Subproject e6b0764799309b96c46f4c77e3ea2aa670f15e8
diff --git a/ZAPDTR/ZAPD/ImageBackend.cpp b/ZAPDTR/ZAPD/ImageBackend.cpp
deleted file mode 100644
index 7ebb29121..000000000
--- a/ZAPDTR/ZAPD/ImageBackend.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-#include "ImageBackend.h"
-
-#include <cassert>
-#include <cstdlib>
-#include <png.h>
-#include <stdexcept>
-
-#include "Utils/StringHelper.h"
-#include "WarningHandler.h"
-
-/* ImageBackend */
-
-ImageBackend::~ImageBackend()
-{
- FreeImageData();
-}
-
-void ImageBackend::ReadPng(const char* filename)
-{
- FreeImageData();
-
- FILE* fp = fopen(filename, "rb");
- if (fp == nullptr)
- {
- std::string errorHeader = StringHelper::Sprintf("could not open file '%s'", filename);
- HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
- }
-
- png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
- if (png == nullptr)
- {
- HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
- }
-
- png_infop info = png_create_info_struct(png);
- if (info == nullptr)
- {
- HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
- }
-
- if (setjmp(png_jmpbuf(png)))
- {
- // TODO: better warning explanation
- HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
- }
-
- png_init_io(png, fp);
-
- png_read_info(png, info);
-
- width = png_get_image_width(png, info);
- height = png_get_image_height(png, info);
- colorType = png_get_color_type(png, info);
- bitDepth = png_get_bit_depth(png, info);
-
-#ifdef TEXTURE_DEBUG
- printf("Width: %u\n", width);
- printf("Height: %u\n", height);
- printf("ColorType: ");
- switch (colorType)
- {
- case PNG_COLOR_TYPE_RGBA:
- printf("PNG_COLOR_TYPE_RGBA\n");
- break;
-
- case PNG_COLOR_TYPE_RGB:
- printf("PNG_COLOR_TYPE_RGB\n");
- break;
-
- case PNG_COLOR_TYPE_PALETTE:
- printf("PNG_COLOR_TYPE_PALETTE\n");
- break;
-
- default:
- printf("%u\n", colorType);
- break;
- }
- printf("BitDepth: %u\n", bitDepth);
- printf("\n");
-#endif
-
- // Read any color_type into 8bit depth, RGBA format.
- // See http://www.libpng.org/pub/png/libpng-manual.txt
-
- if (bitDepth == 16)
- png_set_strip_16(png);
-
- if (colorType == PNG_COLOR_TYPE_PALETTE)
- {
- // png_set_palette_to_rgb(png);
- isColorIndexed = true;
- }
-
- // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
- if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
- png_set_expand_gray_1_2_4_to_8(png);
-
- /*if (png_get_valid(png, info, PNG_INFO_tRNS))
- png_set_tRNS_to_alpha(png);*/
-
- // These color_type don't have an alpha channel then fill it with 0xff.
- /*if(*color_type == PNG_COLOR_TYPE_RGB ||
- *color_type == PNG_COLOR_TYPE_GRAY ||
- *color_type == PNG_COLOR_TYPE_PALETTE)
- png_set_filler(png, 0xFF, PNG_FILLER_AFTER);*/
-
- if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png);
-
- png_read_update_info(png, info);
-
- size_t rowBytes = png_get_rowbytes(png, info);
- pixelMatrix = (uint8_t**)malloc(sizeof(uint8_t*) * height);
- for (size_t y = 0; y < height; y++)
- {
- pixelMatrix[y] = (uint8_t*)malloc(rowBytes);
- }
-
- png_read_image(png, pixelMatrix);
-
-#ifdef TEXTURE_DEBUG
- printf("rowBytes: %zu\n", rowBytes);
-
- size_t bytePerPixel = GetBytesPerPixel();
- printf("imgData\n");
- for (size_t y = 0; y < height; y++)
- {
- for (size_t x = 0; x < width; x++)
- {
- for (size_t z = 0; z < bytePerPixel; z++)
- {
- printf("%02X ", pixelMatrix[y][x * bytePerPixel + z]);
- }
- printf(" ");
- }
- printf("\n");
- }
- printf("\n");
-#endif
-
- fclose(fp);
-
- png_destroy_read_struct(&png, &info, nullptr);
-
- hasImageData = true;
-}
-
-void ImageBackend::ReadPng(const fs::path& filename)
-{
- ReadPng(filename.string().c_str());
-}
-
-void ImageBackend::WritePng(const char* filename)
-{
- assert(hasImageData);
-
- FILE* fp = fopen(filename, "wb");
- if (fp == nullptr)
- {
- std::string errorHeader =
- StringHelper::Sprintf("could not open file '%s' in write mode", filename);
- HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
- }
-
- png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
- if (png == nullptr)
- {
- HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
- }
-
- png_infop info = png_create_info_struct(png);
- if (info == nullptr)
- {
- HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
- }
-
- if (setjmp(png_jmpbuf(png)))
- {
- // TODO: better warning description
- HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
- }
-
- png_init_io(png, fp);
-
- png_set_IHDR(png, info, width, height,
- bitDepth, // 8,
- colorType, // PNG_COLOR_TYPE_RGBA,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- if (isColorIndexed)
- {
- png_set_PLTE(png, info, static_cast<png_color*>(colorPalette), paletteSize);
-
-#ifdef TEXTURE_DEBUG
- printf("palette\n");
- png_color* aux = (png_color*)colorPalette;
- for (size_t y = 0; y < paletteSize; y++)
- {
- printf("#%02X%02X%02X ", aux[y].red, aux[y].green, aux[y].blue);
- if ((y + 1) % 8 == 0)
- printf("\n");
- }
- printf("\n");
-#endif
-
- png_set_tRNS(png, info, alphaPalette, paletteSize, nullptr);
- }
-
- png_write_info(png, info);
-
- // To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
- // Use png_set_filler().
- // png_set_filler(png, 0, PNG_FILLER_AFTER);
-
-#ifdef TEXTURE_DEBUG
- size_t bytePerPixel = GetBytesPerPixel();
- printf("imgData\n");
- for (size_t y = 0; y < height; y++)
- {
- for (size_t x = 0; x < width * bytePerPixel; x++)
- {
- printf("%02X ", pixelMatrix[y][x]);
- }
- printf("\n");
- }
- printf("\n");
-#endif
-
- png_write_image(png, pixelMatrix);
- png_write_end(png, nullptr);
-
- fclose(fp);
-
- png_destroy_write_struct(&png, &info);
-}
-
-void ImageBackend::WritePng(const fs::path& filename)
-{
- // Note: The .string() is necessary for MSVC, due to the implementation of std::filesystem
- // differing from GCC. Do not remove!
- WritePng(filename.string().c_str());
-}
-
-void ImageBackend::SetTextureData(const std::vector<std::vector<RGBAPixel>>& texData,
- uint32_t nWidth, uint32_t nHeight, uint8_t nColorType,
- uint8_t nBitDepth)
-{
- FreeImageData();
-
- width = nWidth;
- height = nHeight;
- colorType = nColorType;
- bitDepth = nBitDepth;
-
- size_t bytePerPixel = GetBytesPerPixel();
-
- pixelMatrix = static_cast<uint8_t**>(malloc(sizeof(uint8_t*) * height));
- for (size_t y = 0; y < height; y++)
- {
- pixelMatrix[y] = static_cast<uint8_t*>(malloc(sizeof(uint8_t*) * width * bytePerPixel));
- for (size_t x = 0; x < width; x++)
- {
- pixelMatrix[y][x * bytePerPixel + 0] = texData.at(y).at(x).r;
- pixelMatrix[y][x * bytePerPixel + 1] = texData.at(y).at(x).g;
- pixelMatrix[y][x * bytePerPixel + 2] = texData.at(y).at(x).b;
-
- if (colorType == PNG_COLOR_TYPE_RGBA)
- pixelMatrix[y][x * bytePerPixel + 3] = texData.at(y).at(x).a;
- }
- }
- hasImageData = true;
-}
-
-void ImageBackend::InitEmptyRGBImage(uint32_t nWidth, uint32_t nHeight, bool alpha)
-{
- FreeImageData();
-
- width = nWidth;
- height = nHeight;
- colorType = PNG_COLOR_TYPE_RGB;
- if (alpha)
- colorType = PNG_COLOR_TYPE_RGBA;
- bitDepth = 8; // nBitDepth;
-
- size_t bytePerPixel = GetBytesPerPixel();
-
- pixelMatrix = static_cast<uint8_t**>(malloc(sizeof(uint8_t*) * height));
- for (size_t y = 0; y < height; y++)
- {
- pixelMatrix[y] = static_cast<uint8_t*>(calloc(width * bytePerPixel, sizeof(uint8_t*)));
- }
-
- hasImageData = true;
-}
-
-void ImageBackend::InitEmptyPaletteImage(uint32_t nWidth, uint32_t nHeight)
-{
- FreeImageData();
-
- width = nWidth;
- height = nHeight;
- colorType = PNG_COLOR_TYPE_PALETTE;
- bitDepth = 8;
-
- size_t bytePerPixel = GetBytesPerPixel();
-
- pixelMatrix = (uint8_t**)malloc(sizeof(uint8_t*) * height);
- for (size_t y = 0; y < height; y++)
- {
- pixelMatrix[y] = static_cast<uint8_t*>(calloc(width * bytePerPixel, sizeof(uint8_t*)));
- }
- colorPalette = calloc(paletteSize, sizeof(png_color));
- alphaPalette = static_cast<uint8_t*>(calloc(paletteSize, sizeof(uint8_t)));
-
- hasImageData = true;
- isColorIndexed = true;
-}
-
-RGBAPixel ImageBackend::GetPixel(size_t y, size_t x) const
-{
- assert(y < height);
- assert(x < width);
- assert(!isColorIndexed);
-
- RGBAPixel pixel;
- size_t bytePerPixel = GetBytesPerPixel();
- pixel.r = pixelMatrix[y][x * bytePerPixel + 0];
- pixel.g = pixelMatrix[y][x * bytePerPixel + 1];
- pixel.b = pixelMatrix[y][x * bytePerPixel + 2];
- if (colorType == PNG_COLOR_TYPE_RGBA)
- pixel.a = pixelMatrix[y][x * bytePerPixel + 3];
- return pixel;
-}
-
-uint8_t ImageBackend::GetIndexedPixel(size_t y, size_t x) const
-{
- assert(y < height);
- assert(x < width);
- assert(isColorIndexed);
-
- return pixelMatrix[y][x];
-}
-
-void ImageBackend::SetRGBPixel(size_t y, size_t x, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
-{
- assert(hasImageData);
- assert(y < height);
- assert(x < width);
-
- size_t bytePerPixel = GetBytesPerPixel();
- pixelMatrix[y][x * bytePerPixel + 0] = nR;
- pixelMatrix[y][x * bytePerPixel + 1] = nG;
- pixelMatrix[y][x * bytePerPixel + 2] = nB;
- if (colorType == PNG_COLOR_TYPE_RGBA)
- pixelMatrix[y][x * bytePerPixel + 3] = nA;
-}
-
-void ImageBackend::SetGrayscalePixel(size_t y, size_t x, uint8_t grayscale, uint8_t alpha)
-{
- assert(hasImageData);
- assert(y < height);
- assert(x < width);
-
- size_t bytePerPixel = GetBytesPerPixel();
- pixelMatrix[y][x * bytePerPixel + 0] = grayscale;
- pixelMatrix[y][x * bytePerPixel + 1] = grayscale;
- pixelMatrix[y][x * bytePerPixel + 2] = grayscale;
- if (colorType == PNG_COLOR_TYPE_RGBA)
- pixelMatrix[y][x * bytePerPixel + 3] = alpha;
-}
-
-void ImageBackend::SetIndexedPixel(size_t y, size_t x, uint8_t index, uint8_t grayscale)
-{
- assert(hasImageData);
- assert(y < height);
- assert(x < width);
-
- size_t bytePerPixel = GetBytesPerPixel();
- pixelMatrix[y][x * bytePerPixel + 0] = index;
-
- assert(index < paletteSize);
- png_color* pal = static_cast<png_color*>(colorPalette);
- pal[index].red = grayscale;
- pal[index].green = grayscale;
- pal[index].blue = grayscale;
- alphaPalette[index] = 255;
-}
-
-void ImageBackend::SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
-{
- assert(isColorIndexed);
- assert(index < paletteSize);
-
- png_color* pal = static_cast<png_color*>(colorPalette);
- pal[index].red = nR;
- pal[index].green = nG;
- pal[index].blue = nB;
- alphaPalette[index] = nA;
-}
-
-void ImageBackend::SetPalette(const ImageBackend& pal, uint32_t offset)
-{
- assert(isColorIndexed);
- size_t bytePerPixel = pal.GetBytesPerPixel();
-
- for (size_t y = 0; y < pal.height; y++)
- {
- for (size_t x = 0; x < pal.width; x++)
- {
- size_t index = y * pal.width + x;
- if (index >= paletteSize)
- {
- /*
- * Some TLUTs are bigger than 256 colors.
- * For those cases, we will only take the first 256
- * to colorize this CI texture.
- */
- return;
- }
-
- uint8_t r = pal.pixelMatrix[y][x * bytePerPixel + 0];
- uint8_t g = pal.pixelMatrix[y][x * bytePerPixel + 1];
- uint8_t b = pal.pixelMatrix[y][x * bytePerPixel + 2];
- uint8_t a = pal.pixelMatrix[y][x * bytePerPixel + 3];
- SetPaletteIndex(index + offset, r, g, b, a);
- }
- }
-}
-
-uint32_t ImageBackend::GetWidth() const
-{
- return width;
-}
-
-uint32_t ImageBackend::GetHeight() const
-{
- return height;
-}
-
-uint8_t ImageBackend::GetColorType() const
-{
- return colorType;
-}
-
-uint8_t ImageBackend::GetBitDepth() const
-{
- return bitDepth;
-}
-
-double ImageBackend::GetBytesPerPixel() const
-{
- switch (colorType)
- {
- case PNG_COLOR_TYPE_RGBA:
- return 4 * bitDepth / 8;
-
- case PNG_COLOR_TYPE_RGB:
- return 3 * bitDepth / 8;
-
- case PNG_COLOR_TYPE_PALETTE:
- return 1 * bitDepth / 8;
-
- default:
- HANDLE_ERROR(WarningType::InvalidPNG, "invalid color type", "");
- }
-}
-
-void ImageBackend::FreeImageData()
-{
- if (hasImageData)
- {
- for (size_t y = 0; y < height; y++)
- free(pixelMatrix[y]);
- free(pixelMatrix);
- pixelMatrix = nullptr;
- }
-
- if (isColorIndexed)
- {
- free(colorPalette);
- free(alphaPalette);
- colorPalette = nullptr;
- alphaPalette = nullptr;
- isColorIndexed = false;
- }
-
- hasImageData = false;
-}
-
-/* RGBAPixel */
-
-void RGBAPixel::SetRGBA(uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
-{
- r = nR;
- g = nG;
- b = nB;
- a = nA;
-}
-
-void RGBAPixel::SetGrayscale(uint8_t grayscale, uint8_t alpha)
-{
- r = grayscale;
- g = grayscale;
- b = grayscale;
- a = alpha;
-}