Fixed errored pixels conversion

This commit is contained in:
JackCarterSmith 2019-07-21 14:39:53 +02:00
parent fa8d44fa41
commit 716d7ff496
7 changed files with 92 additions and 79 deletions

1
.gitignore vendored
View File

@ -41,6 +41,7 @@
*.su *.su
*.idb *.idb
*.pdb *.pdb
testfiles/
# Kernel Module Compile Results # Kernel Module Compile Results
*.mod* *.mod*

View File

@ -52,7 +52,7 @@ int readMaterial(HMT_MATERIAL *mat, FILE *hmt_src) {
} }
int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) { int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) {
char u0,u1,bpp; unsigned char u0,u1,bpp;
long pos; long pos;
RS_IMAGE_DESC desc; RS_IMAGE_DESC desc;
@ -78,7 +78,7 @@ int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) {
fseek(hmt_src, pos, SEEK_SET); fseek(hmt_src, pos, SEEK_SET);
desc = getImageDescFromType(tex->image.type_); desc = getImageDescFromType(tex->image.type_);
tex->image.paletteEntries = desc.palette_enties; tex->image.paletteEntries = desc.palette_entries;
tex->image.sampleBits = desc.sample_bits; tex->image.sampleBits = desc.sample_bits;
tex->image.width = tex->width; tex->image.width = tex->width;
tex->image.height = tex->height; tex->image.height = tex->height;
@ -106,6 +106,37 @@ int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int getPaletteFromFile(RS_IMAGE *img, FILE *f) {
int entries = img->paletteEntries;
switch (entries) {
case 16:
case 256:
fread(img->palette, sizeof(PIXEL), entries, f);
break;
default:
break;
}
return EXIT_SUCCESS;
}
int getSamplesFromFile(RS_IMAGE *img, FILE *f) {
int sample_bits = img->sampleBits;
int size = div(img->width*img->height*sample_bits, 8).quot;
if (f->_bufsiz >= ftell(f)+size) {
printf("WARNING! Please fix size/sample.");
return EXIT_FAILURE;
}
img->samples = calloc(1, size);
fread(img->samples, size, 1, f);
if (img->type_ == 2) fread(img->samples, div(size, 4).quot, 1, f);
return EXIT_SUCCESS;
}
void purgeHMTFromMemory(HMT_FILE *_f) { void purgeHMTFromMemory(HMT_FILE *_f) {
if (_f == NULL) return; if (_f == NULL) return;

View File

@ -100,6 +100,8 @@ HMT_MATERIAL *getMaterialFromIndex(int i);
HMT_MATERIAL *getMaterialFromName(char *matName); HMT_MATERIAL *getMaterialFromName(char *matName);
HMT_TEXTURE *getTextureFromIndex(int i); HMT_TEXTURE *getTextureFromIndex(int i);
HMT_TEXTURE *getTextureFromMaterial(HMT_MATERIAL *mat); HMT_TEXTURE *getTextureFromMaterial(HMT_MATERIAL *mat);
int getPaletteFromFile(RS_IMAGE *img, FILE *f);
int getSamplesFromFile(RS_IMAGE *img, FILE *f);
void purgeHMTFromMemory(HMT_FILE *_f); void purgeHMTFromMemory(HMT_FILE *_f);
#endif #endif

View File

@ -52,13 +52,6 @@ int saveToPNG(RS_IMAGE *img, char *tex_path, char *hmt_fileName) {
*row++ = pixel->_alpha; *row++ = pixel->_alpha;
} }
} }
/*
if (img->paletteEntries == 0 || img->sampleBits == 32 || img->sampleBits == 16) {
memcpy(row_ptrs, img->pixels, sizeof(*img->pixels)*img->height*img->width);
} else {
memcpy(row_ptrs, img->pixels, sizeof(*img->pixels)*3*img->height*img->width);
}
*/
png_init_io(png_ptr, _png_f); png_init_io(png_ptr, _png_f);
png_set_rows(png_ptr, info_ptr, row_ptrs); png_set_rows(png_ptr, info_ptr, row_ptrs);

View File

@ -1,38 +1,5 @@
#include "RS_images.h" #include "RS_images.h"
#define PIXEL_MEMBERS_NBR 4
int getPaletteFromFile(RS_IMAGE *img, FILE *f) {
int entries = img->paletteEntries;
switch (entries) {
case 16:
case 256:
fread(img->palette, sizeof(unsigned char), entries*3, f);
break;
default:
break;
}
return EXIT_SUCCESS;
}
int getSamplesFromFile(RS_IMAGE *img, FILE *f) {
int sample_bits = img->sampleBits;
int size = div(img->width*img->height*sample_bits, 8).quot;
if (f->_bufsiz >= ftell(f)+size) {
printf("WARNING! Please fix size/sample.");
return EXIT_FAILURE;
}
img->samples = calloc(1, size);
fread(img->samples, size, 1, f);
if (img->type_ == 2) fread(img->samples, div(size, 4).quot, 1, f);
return EXIT_SUCCESS;
}
void decodePixels(RS_IMAGE *img) { void decodePixels(RS_IMAGE *img) {
int size; int size;
@ -45,36 +12,30 @@ void decodePixels(RS_IMAGE *img) {
img->type_ == 4 || img->type_ == 4 ||
img->type_ == 5)) return; img->type_ == 5)) return;
size = img->height * img->width;
switch (img->sampleBits) { switch (img->sampleBits) {
case 32: case 32:
size = img->width * img->height * 4; img->pixels = calloc(1, size * sizeof(PIXEL_A));
img->pixels = calloc(1, size); memcpy(img->pixels, img->samples, size * sizeof(PIXEL_A));
memcpy(img->pixels, img->samples, size);
break; break;
case 4: case 4:
img->pixels = calloc(1, size * sizeof(PIXEL_A));
if (img->paletteEntries == 0) { if (img->paletteEntries == 0) {
size = sizeof(PIXEL_A) * img->height * img->width; convert4bitsGreyTo32bitsRGBA(img->samples, img->pixels, size, &(img->alpha_color));
img->pixels = calloc(1, size);
convert4bitsGreyto8bitsRGB(img->samples, img->pixels, div(size, PIXEL_MEMBERS_NBR).quot, &(img->alpha_color));
} else if (img->paletteEntries == 16) { } else if (img->paletteEntries == 16) {
size = img->width * img->height; convert4bitsTo32bitsRGBA(img->samples, img->pixels, size, img->palette, &(img->alpha_color));
img->pixels = calloc(1, size*3);
unpack4To24bitsRGB(img->samples, img->pixels, size, img->palette);
} }
break; break;
case 8: case 8:
if (img->paletteEntries == 0) { if (img->paletteEntries == 0) {
size = img->width * img->height;
img->pixels = calloc(1, size); img->pixels = calloc(1, size);
memcpy(img->pixels, img->samples, size); memcpy(img->pixels, img->samples, size);
} else if (img->paletteEntries == 256) { } else if (img->paletteEntries == 256) {
size = img->width * img->height; img->pixels = calloc(1, size * sizeof(PIXEL_A));
img->pixels = calloc(1, size*3); convert8bitsTo32bitsRGBA(img->samples, img->pixels, size, img->palette, &(img->alpha_color));
unpack8To24bitsRGB(img->samples, img->pixels, size, img->palette);
} }
break; break;
case 16: case 16:
size = img->width * img->height;
img->pixels = calloc(1, size); img->pixels = calloc(1, size);
useOddBytes(img->samples, img->pixels, size); useOddBytes(img->samples, img->pixels, size);
break; break;
@ -93,7 +54,7 @@ int isTransparentColor(PIXEL_A *testColor, PIXEL_A *transp_color) {
return 0; return 0;
} }
void convert4bitsGreyto8bitsRGB(unsigned char *samples_tab, PIXEL_A *pixels_tab, int sampling, PIXEL_A *transp_color) { void convert4bitsGreyTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int sampling, PIXEL_A *transp_color) {
int i; int i;
unsigned char v; unsigned char v;
@ -110,30 +71,39 @@ void convert4bitsGreyto8bitsRGB(unsigned char *samples_tab, PIXEL_A *pixels_tab,
} }
} }
void unpack4To24bitsRGB(unsigned char *samples_tab, unsigned char *pixels_tab, int size, unsigned char pal[256][3]) { void convert4bitsTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int size, PIXEL *pal, PIXEL_A *transp_color) {
int i,index; int i,index;
for(i=0; i<div(size,2).quot; i++) { for(i=0; i<div(size,2).quot; i++) {
index = samples_tab[i]; index = samples_tab[i];
memcpy(&(pixels_tab[i*2]), pal[(index >> 4) & 0xF], sizeof(unsigned char)*3); pixels_tab[i*2]._red = pal[(index >> 4) & 0xF]._red;
memcpy(&(pixels_tab[i*2+1]), pal[index & 0xF], sizeof(unsigned char)*3); pixels_tab[i*2]._green = pal[(index >> 4) & 0xF]._green;
pixels_tab[i*2]._blue = pal[(index >> 4) & 0xF]._blue;
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 = pal[index & 0xF]._red;
pixels_tab[i*2+1]._green = pal[index & 0xF]._green;
pixels_tab[i*2+1]._blue = pal[index & 0xF]._blue;
if (isTransparentColor(&(pixels_tab[i*2+1]), transp_color) == 0) pixels_tab[i*2]._alpha = 0xFF - transp_color->_alpha; else pixels_tab[i*2+1]._alpha = 0xFF; // Test if color is a transparent color and adjust alpha layer
} }
} }
void unpack8To24bitsRGB(unsigned char *samples_tab, unsigned char *pixels_tab, int size, unsigned char pal[256][3]) { void convert8bitsTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int size, PIXEL *pal, PIXEL_A *transp_color) {
int i,index; int i,index;
for(i=0; i<size; i++) { for(i=0; i<size; i++) {
index = samples_tab[i]; index = samples_tab[i];
memcpy(&(pixels_tab[i]), pal[index], sizeof(unsigned char)*3); pixels_tab[i]._red = pal[index]._red;
pixels_tab[i]._green = pal[index]._green;
pixels_tab[i]._blue = pal[index]._blue;
if (isTransparentColor(&(pixels_tab[i]), transp_color) == 0) pixels_tab[i]._alpha = 0xFF - transp_color->_alpha; else pixels_tab[i]._alpha = 0xFF; // Test if color is a transparent color and adjust alpha layer
} }
} }
void useOddBytes(unsigned char *src, unsigned char *dst, int size) { void useOddBytes(unsigned char *src, PIXEL_A *dst, int size) {
int i; int i;
for(i=0; i<size; i++) { for(i=0; i<size; i++) {
dst[i] = src[i*2+1]; //dst[i] = src[i*2+1];
} }
} }
@ -146,27 +116,27 @@ RS_IMAGE_DESC getImageDescFromType(unsigned char type) {
switch(type) { switch(type) {
case 0: case 0:
desc.palette_enties = 16; desc.palette_entries = 16;
desc.sample_bits = 4; desc.sample_bits = 4;
break; break;
case 1: case 1:
desc.palette_enties = 256; desc.palette_entries = 256;
desc.sample_bits = 8; desc.sample_bits = 8;
break; break;
case 2: case 2:
desc.palette_enties = 0; desc.palette_entries = 0;
desc.sample_bits = 16; desc.sample_bits = 16;
break; break;
case 3: case 3:
desc.palette_enties = 0; desc.palette_entries = 0;
desc.sample_bits = 32; desc.sample_bits = 32;
break; break;
case 4: case 4:
desc.palette_enties = 0; desc.palette_entries = 0;
desc.sample_bits = 4; desc.sample_bits = 4;
break; break;
case 5: case 5:
desc.palette_enties = 0; desc.palette_entries = 0;
desc.sample_bits = 8; desc.sample_bits = 8;
break; break;
default: default:

View File

@ -4,6 +4,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
/**
* @brief Constant contain the number of channel inside a PIXEL definition.
*/
#define PIXEL_MEMBERS_NBR 4
///////////////////////////// /////////////////////////////
@ -41,11 +45,11 @@ typedef struct RSImage {
PIXEL_A alpha_color; PIXEL_A alpha_color;
PIXEL_A *pixels; /**< Image pixels list, managed like an array and declared as a pointer */ 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 *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 PIXEL palette[256]; /**< Image palette definition */ //TODO: Create union struct type instead
}RS_IMAGE; }RS_IMAGE;
typedef struct RSImage_desc { typedef struct RSImage_desc {
int palette_enties; int palette_entries;
int sample_bits; int sample_bits;
}RS_IMAGE_DESC; }RS_IMAGE_DESC;
@ -53,15 +57,27 @@ typedef struct RSImage_desc {
///////////////////////////// /////////////////////////////
///// Declare functions ///// ///// Declare functions /////
///////////////////////////// /////////////////////////////
/**
* @brief Conversion table for image type using RS_IMAGE_DESC.
* Return RS_IMAGE_DESC by providing image type as int\n
*
* Detailed conversion:\n\n
* Type 0 -> Palette entries: 16 ; Sample bits: 4\n
* Type 1 -> Palette entries: 256 ; Sample bits: 8\n
* Type 2 -> Palette entries: 0 ; Sample bits: 16\n
* Type 3 -> Palette entries: 0 ; Sample bits: 32\n
* Type 4 -> Palette entries: 0 ; Sample bits: 4\n
* Type 5 -> Palette entries: 0 ; Sample bits: 8\n
*/
RS_IMAGE_DESC getImageDescFromType(unsigned char type); //TODO: Optimise function RS_IMAGE_DESC getImageDescFromType(unsigned char type); //TODO: Optimise function
int isTransparentColor(PIXEL_A *testColor, PIXEL_A *transp_color); 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 convert4bitsGreyTo32bitsRGBA(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 convert4bitsTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int size, PIXEL *pal, PIXEL_A *transp_color);
void unpack8To24bitsRGB(unsigned char *samples_tab, unsigned char *pixels_tab, int size, unsigned char pal[256][3]); void convert8bitsTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int size, PIXEL *pal, PIXEL_A *transp_color);
void useOddBytes(unsigned char *src, unsigned char *dst, int size); void useOddBytes(unsigned char *src, PIXEL_A *dst, int size);
void decodePixels(RS_IMAGE *img); void decodePixels(RS_IMAGE *img);
PIXEL_A *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);
#endif #endif

View File

@ -2,7 +2,7 @@
================================================================================ ================================================================================
Name : Texture-Extractor.c Name : Texture-Extractor.c
Author : JackCarterSmith Author : JackCarterSmith
Version : 0.2 Version : 1.0
License : GPL-v3.0 License : GPL-v3.0
Description : DAT textures extractor to PNG format with enhanced function in C Description : DAT textures extractor to PNG format with enhanced function in C
================================================================================ ================================================================================