Added support for alpha channel

This commit is contained in:
JackCarterSmith 2019-07-20 21:51:36 +02:00
parent 6df772741b
commit b147df2364
4 changed files with 44 additions and 14 deletions

View File

@ -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) {

View File

@ -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; y<img->height; 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; x<img->width; 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;
}
}
/*

View File

@ -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;
}

View File

@ -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);