diff --git a/src/HMT_Parser.c b/src/HMT_Parser.c index 4848294..1d69e23 100644 --- a/src/HMT_Parser.c +++ b/src/HMT_Parser.c @@ -53,7 +53,6 @@ int readMaterial(HMT_MATERIAL *mat, FILE *hmt_src) { int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) { char u0,u1,bpp; - int color_rgba; long pos; RS_IMAGE_DESC desc; @@ -68,7 +67,10 @@ int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) { fread(&bpp, 1, 1, hmt_src); fread(&(tex->image.type_), 1, 1, hmt_src); fread(&u1, 1, 1, hmt_src); - fread(&color_rgba, 4, 1, hmt_src); + fread(&(tex->image.alpha_color._red), 1, 1, hmt_src); + fread(&(tex->image.alpha_color._green), 1, 1, hmt_src); + fread(&(tex->image.alpha_color._blue), 1, 1, hmt_src); + fread(&(tex->image.alpha_color._alpha), 1, 1, hmt_src); pos = ftell(hmt_src); fseek(hmt_src, tex->textureName_offset, SEEK_SET); @@ -81,11 +83,13 @@ int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) { tex->image.width = tex->width; tex->image.height = tex->height; + printf("\n"); printf("Texture name: %s\n", tex->name); printf("Size w: %ld h: %ld\n", tex->width, tex->height); printf("Texture subtype: %d\n", tex->image.type_); printf("Palette offset: %d\n", tex->palette_offset); printf("Data offset: %d\n", tex->data_offset); + printf("Transparent color (RGB): %X %X %X\n", tex->image.alpha_color._red, tex->image.alpha_color._green, tex->image.alpha_color._blue); printf("u0: %d u1: %d\n", u0, u1); if (tex->palette_offset > 0) { diff --git a/src/Image_Exporter.c b/src/Image_Exporter.c index f430f3c..7093b2e 100644 --- a/src/Image_Exporter.c +++ b/src/Image_Exporter.c @@ -8,7 +8,7 @@ int saveToPNG(RS_IMAGE *img, char *tex_name) { png_infop info_ptr = NULL; size_t x,y; png_byte **row_ptrs = NULL; - PIXEL *pixel = NULL; + PIXEL_A *pixel = NULL; //int pixel_size = 3; //int depth = 8; //bit par color channel (RGB) @@ -28,12 +28,12 @@ int saveToPNG(RS_IMAGE *img, char *tex_name) { } // Set image attributes - png_set_IHDR(png_ptr, info_ptr, img->width, img->height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(png_ptr, info_ptr, img->width, img->height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); // Init PNG datas row_ptrs = png_malloc(png_ptr, img->height * sizeof(png_byte *)); for (y=0; yheight; y++) { - png_byte *row = png_malloc(png_ptr, img->width*sizeof(PIXEL)); + png_byte *row = png_malloc(png_ptr, img->width*sizeof(PIXEL_A)); row_ptrs[y] = row; for (x=0; xwidth; x++) { pixel = pixelAt(img, x , y); @@ -42,6 +42,7 @@ int saveToPNG(RS_IMAGE *img, char *tex_name) { *row++ = pixel->_red; *row++ = pixel->_green; *row++ = pixel->_blue; + *row++ = pixel->_alpha; } } /* diff --git a/src/RS_images.c b/src/RS_images.c index f11946c..4713c29 100644 --- a/src/RS_images.c +++ b/src/RS_images.c @@ -1,5 +1,7 @@ #include "RS_images.h" +#define PIXEL_MEMBERS_NBR 4 + int getPaletteFromFile(RS_IMAGE *img, FILE *f) { int entries = img->paletteEntries; @@ -51,9 +53,9 @@ void decodePixels(RS_IMAGE *img) { break; case 4: if (img->paletteEntries == 0) { - size = sizeof(PIXEL) * img->height * img->width; + size = sizeof(PIXEL_A) * img->height * img->width; img->pixels = calloc(1, size); - convert4bitsGreyto8bitsRGB(img->samples, img->pixels, div(size,3).quot); + convert4bitsGreyto8bitsRGB(img->samples, img->pixels, div(size, PIXEL_MEMBERS_NBR).quot, &(img->alpha_color)); } else if (img->paletteEntries == 16) { size = img->width * img->height; img->pixels = calloc(1, size*3); @@ -81,7 +83,17 @@ void decodePixels(RS_IMAGE *img) { } } -void convert4bitsGreyto8bitsRGB(unsigned char *samples_tab, PIXEL *pixels_tab, int sampling) { +int isTransparentColor(PIXEL_A *testColor, PIXEL_A *transp_color) { + if (transp_color == NULL || testColor == NULL) return -2; + + if (!(testColor->_red == transp_color->_red)) return -1; + if (!(testColor->_green == transp_color->_green)) return -1; + if (!(testColor->_blue == transp_color->_blue)) return -1; + + return 0; +} + +void convert4bitsGreyto8bitsRGB(unsigned char *samples_tab, PIXEL_A *pixels_tab, int sampling, PIXEL_A *transp_color) { int i; unsigned char v; @@ -90,9 +102,11 @@ void convert4bitsGreyto8bitsRGB(unsigned char *samples_tab, PIXEL *pixels_tab, i pixels_tab[i*2]._red = div((v >> 4 & 0xF) * 256, 16).quot; pixels_tab[i*2]._green = div((v >> 4 & 0xF) * 256, 16).quot; pixels_tab[i*2]._blue = div((v >> 4 & 0xF) * 256, 16).quot; + if (isTransparentColor(&(pixels_tab[i*2]), transp_color) == 0) pixels_tab[i*2]._alpha = 0xFF - transp_color->_alpha; else pixels_tab[i*2]._alpha = 0xFF; // Test if color is a transparent color and adjust alpha layer pixels_tab[i*2+1]._red = div((v & 0xF) * 256, 16).quot; pixels_tab[i*2+1]._green = div((v & 0xF) * 256, 16).quot; pixels_tab[i*2+1]._blue = div((v & 0xF) * 256, 16).quot; + if (isTransparentColor(&(pixels_tab[i*2+1]), transp_color) == 0) pixels_tab[i*2+1]._alpha = 0xFF - transp_color->_alpha; else pixels_tab[i*2+1]._alpha = 0xFF; // Test if color is a transparent color and adjust alpha layer } } @@ -123,7 +137,7 @@ void useOddBytes(unsigned char *src, unsigned char *dst, int size) { } } -PIXEL *pixelAt(RS_IMAGE *img, int posX , int posY) { +PIXEL_A *pixelAt(RS_IMAGE *img, int posX , int posY) { return img->pixels + img->width * posY + posX; } diff --git a/src/RS_images.h b/src/RS_images.h index d3be214..b8c1495 100644 --- a/src/RS_images.h +++ b/src/RS_images.h @@ -18,7 +18,17 @@ ///////////////////////////// /** - * @brief RGB pixel structure, used to store datas for implementation inside PNG files + * @brief RGBA pixel structure, used to store datas for implementation inside PNG files. + */ +typedef struct PixelRGBA { + unsigned char _red; + unsigned char _green; + unsigned char _blue; + unsigned char _alpha; +}PIXEL_A; + +/** + * @brief RGB pixel structure, used to store datas for implementation inside PNG files, optimised version without alpha channel support. */ typedef struct PixelRGB { unsigned char _red; @@ -35,7 +45,8 @@ typedef struct RSImage { unsigned char type_; /**< Image type (0 = RBG/4bits per pixel, 1 = RBG/8bpp, 3 = RGBA/32bpp , 4 = grayscale/4bpp, 5 = grayscale/8bpp */ unsigned char sampleBits; /**< Bits per samble */ int paletteEntries; - PIXEL *pixels; /**< Image pixels list, managed like an array and declared as a pointer */ + PIXEL_A alpha_color; + PIXEL_A *pixels; /**< Image pixels list, managed like an array and declared as a pointer */ unsigned char *samples; /**< Image samples list managed like an array and declared as a pointer */ unsigned char palette[256][3]; /**< Image palette definition */ //TODO: Create union struct type instead }RS_IMAGE; @@ -43,7 +54,6 @@ typedef struct RSImage { typedef struct RSImage_desc { int palette_enties; int sample_bits; - //char alpha; }RS_IMAGE_DESC; @@ -51,12 +61,13 @@ typedef struct RSImage_desc { ///// Declare functions ///// ///////////////////////////// RS_IMAGE_DESC getImageDescFromType(unsigned char type); //TODO: Optimise function -void convert4bitsGreyto8bitsRGB(unsigned char *samples_tab, PIXEL *pixels_tab, int sampling); +int isTransparentColor(PIXEL_A *testColor, PIXEL_A *transp_color); +void convert4bitsGreyto8bitsRGB(unsigned char *samples_tab, PIXEL_A *pixels_tab, int sampling, PIXEL_A *transp_color); void unpack4To24bitsRGB(unsigned char *samples_tab, unsigned char *pixels_tab, int size, unsigned char pal[256][3]); void unpack8To24bitsRGB(unsigned char *samples_tab, unsigned char *pixels_tab, int size, unsigned char pal[256][3]); void useOddBytes(unsigned char *src, unsigned char *dst, int size); void decodePixels(RS_IMAGE *img); -PIXEL *pixelAt(RS_IMAGE *img, int posX , int posY); +PIXEL_A *pixelAt(RS_IMAGE *img, int posX , int posY); int getPaletteFromFile(RS_IMAGE *img, FILE *f); int getSamplesFromFile(RS_IMAGE *img, FILE *f);