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
*.idb
*.pdb
testfiles/
# Kernel Module Compile Results
*.mod*

View File

@ -52,7 +52,7 @@ int readMaterial(HMT_MATERIAL *mat, FILE *hmt_src) {
}
int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) {
char u0,u1,bpp;
unsigned char u0,u1,bpp;
long pos;
RS_IMAGE_DESC desc;
@ -78,7 +78,7 @@ int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) {
fseek(hmt_src, pos, SEEK_SET);
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.width = tex->width;
tex->image.height = tex->height;
@ -106,6 +106,37 @@ int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) {
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) {
if (_f == NULL) return;

View File

@ -100,6 +100,8 @@ HMT_MATERIAL *getMaterialFromIndex(int i);
HMT_MATERIAL *getMaterialFromName(char *matName);
HMT_TEXTURE *getTextureFromIndex(int i);
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);
#endif

View File

@ -52,13 +52,6 @@ int saveToPNG(RS_IMAGE *img, char *tex_path, char *hmt_fileName) {
*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_set_rows(png_ptr, info_ptr, row_ptrs);

View File

@ -1,38 +1,5 @@
#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) {
int size;
@ -45,36 +12,30 @@ void decodePixels(RS_IMAGE *img) {
img->type_ == 4 ||
img->type_ == 5)) return;
size = img->height * img->width;
switch (img->sampleBits) {
case 32:
size = img->width * img->height * 4;
img->pixels = calloc(1, size);
memcpy(img->pixels, img->samples, size);
img->pixels = calloc(1, size * sizeof(PIXEL_A));
memcpy(img->pixels, img->samples, size * sizeof(PIXEL_A));
break;
case 4:
img->pixels = calloc(1, size * sizeof(PIXEL_A));
if (img->paletteEntries == 0) {
size = sizeof(PIXEL_A) * img->height * img->width;
img->pixels = calloc(1, size);
convert4bitsGreyto8bitsRGB(img->samples, img->pixels, div(size, PIXEL_MEMBERS_NBR).quot, &(img->alpha_color));
convert4bitsGreyTo32bitsRGBA(img->samples, img->pixels, size, &(img->alpha_color));
} else if (img->paletteEntries == 16) {
size = img->width * img->height;
img->pixels = calloc(1, size*3);
unpack4To24bitsRGB(img->samples, img->pixels, size, img->palette);
convert4bitsTo32bitsRGBA(img->samples, img->pixels, size, img->palette, &(img->alpha_color));
}
break;
case 8:
if (img->paletteEntries == 0) {
size = img->width * img->height;
img->pixels = calloc(1, size);
memcpy(img->pixels, img->samples, size);
} else if (img->paletteEntries == 256) {
size = img->width * img->height;
img->pixels = calloc(1, size*3);
unpack8To24bitsRGB(img->samples, img->pixels, size, img->palette);
img->pixels = calloc(1, size * sizeof(PIXEL_A));
convert8bitsTo32bitsRGBA(img->samples, img->pixels, size, img->palette, &(img->alpha_color));
}
break;
case 16:
size = img->width * img->height;
img->pixels = calloc(1, size);
useOddBytes(img->samples, img->pixels, size);
break;
@ -93,7 +54,7 @@ int isTransparentColor(PIXEL_A *testColor, PIXEL_A *transp_color) {
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;
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;
for(i=0; i<div(size,2).quot; i++) {
index = samples_tab[i];
memcpy(&(pixels_tab[i*2]), pal[(index >> 4) & 0xF], sizeof(unsigned char)*3);
memcpy(&(pixels_tab[i*2+1]), pal[index & 0xF], sizeof(unsigned char)*3);
pixels_tab[i*2]._red = pal[(index >> 4) & 0xF]._red;
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;
for(i=0; i<size; 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;
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) {
case 0:
desc.palette_enties = 16;
desc.palette_entries = 16;
desc.sample_bits = 4;
break;
case 1:
desc.palette_enties = 256;
desc.palette_entries = 256;
desc.sample_bits = 8;
break;
case 2:
desc.palette_enties = 0;
desc.palette_entries = 0;
desc.sample_bits = 16;
break;
case 3:
desc.palette_enties = 0;
desc.palette_entries = 0;
desc.sample_bits = 32;
break;
case 4:
desc.palette_enties = 0;
desc.palette_entries = 0;
desc.sample_bits = 4;
break;
case 5:
desc.palette_enties = 0;
desc.palette_entries = 0;
desc.sample_bits = 8;
break;
default:

View File

@ -4,6 +4,10 @@
#include <stdio.h>
#include <stdlib.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 *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
PIXEL palette[256]; /**< Image palette definition */ //TODO: Create union struct type instead
}RS_IMAGE;
typedef struct RSImage_desc {
int palette_enties;
int palette_entries;
int sample_bits;
}RS_IMAGE_DESC;
@ -53,15 +57,27 @@ typedef struct RSImage_desc {
/////////////////////////////
///// 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
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 convert4bitsGreyTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int sampling, PIXEL_A *transp_color);
void convert4bitsTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int size, PIXEL *pal, PIXEL_A *transp_color);
void convert8bitsTo32bitsRGBA(unsigned char *samples_tab, PIXEL_A *pixels_tab, int size, PIXEL *pal, PIXEL_A *transp_color);
void useOddBytes(unsigned char *src, PIXEL_A *dst, int size);
void decodePixels(RS_IMAGE *img);
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

View File

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