--- psiconv/trunk/lib/psiconv/parse_image.c 2003/11/27 20:55:01 175 +++ psiconv/trunk/lib/psiconv/parse_image.c 2003/12/03 15:16:43 178 @@ -24,11 +24,32 @@ #include "parse_routines.h" #include "error.h" +#include "image.h" #ifdef DMALLOC #include #endif +static int psiconv_decode_rle8 (const psiconv_config config, int lev, + psiconv_u32 off, + const psiconv_pixel_bytes encoded, + psiconv_pixel_bytes *decoded); + +static int psiconv_bytes_to_pixel_data(const psiconv_config config, + int lev, psiconv_u32 off, + const psiconv_pixel_bytes bytes, + psiconv_pixel_ints *pixels, + int colordepth, int xsize, int ysize); + +static int psiconv_pixel_data_to_floats (const psiconv_config config, int lev, + psiconv_u32 off, + const psiconv_pixel_ints pixels, + psiconv_pixel_floats_t *floats, + int colordepth, int color, + int redbits, int bluebits, int greenbits, + const psiconv_pixel_floats_t palet); + + int psiconv_parse_jumptable_section(const psiconv_config config, const psiconv_buffer buf,int lev, @@ -657,3 +678,205 @@ else return res; } + +int psiconv_decode_rle8 (const psiconv_config config, int lev, psiconv_u32 off, + const psiconv_pixel_bytes encoded, + psiconv_pixel_bytes *decoded) +{ + int res=0; + psiconv_u8 *marker,*value; + int i,j; + + psiconv_progress(config,lev+1,off,"Going to decode the RLE8 encoding"); + if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8)))) + goto ERROR1; + + for (i = 0; i < psiconv_list_length(encoded);) { + psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i); + if (!(marker = psiconv_list_get(encoded,i))) + goto ERROR2; + psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker); + if (*marker < 0x80) { + psiconv_debug(config,lev+2,off,"Marker: repeat value byte %02x times", + *marker+1); + psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",i+1); + if (!(value = psiconv_list_get(encoded,i+1))) + goto ERROR2; + psiconv_debug(config,lev+2,off,"Value byte: %02x",*value); + psiconv_progress(config,lev+2,off,"Adding %02x bytes %02x", + *marker+1,*value); + for (j = 0; j < *marker + 1; j++) + if ((res = psiconv_list_add(*decoded,value))) + goto ERROR2; + i += 2; + } else { + psiconv_debug(config,lev+2,off,"Marker: %02x value bytes follow", + 0x100 - *marker); + for (j = 0; j < (0x100 - *marker); j++) { + psiconv_progress(config,lev+2,off,"Going to read value byte at %04x", + i+j+1); + if (!(value = psiconv_list_get(encoded,i+j+1))) + goto ERROR2; + psiconv_debug(config,lev+2,off,"Value: %02x",*value); + if ((res = psiconv_list_add(*decoded,value))) + goto ERROR2; + } + i += (0x100 - *marker) + 1; + } + } + psiconv_progress(config,lev,off, + "End of RLE8 decoding process"); + return 0; + +ERROR2: + psiconv_list_free(*decoded); +ERROR1: + psiconv_warn(config,lev+1,off,"Decoding of RLE8 failed"); + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + +int psiconv_bytes_to_pixel_data(const psiconv_config config, + int lev, psiconv_u32 off, + const psiconv_pixel_bytes bytes, + psiconv_pixel_ints *pixels, + int colordepth, int xsize, int ysize) +{ + int res=0; + int ibits,obits,x,y,bits; + psiconv_u8 input; + psiconv_u32 nr,output; + psiconv_u8 *ientry; + + psiconv_progress(config,lev+1,off,"Going to convert the bytes to pixels"); + if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) + goto ERROR1; + + nr = 0; + for (y = 0; y < ysize; y++) { + /* New lines will start at longs */ + while (nr % 4) + nr ++; + input = 0; + ibits = 0; + for (x= 0; x < xsize; x++) { + psiconv_progress(config,lev+2,off, + "Processing pixel at (x,y) = (%04x,%04x)",x,y); + output = 0; + obits = 0; + while (obits < colordepth) { + if (ibits == 0) { + psiconv_progress(config,lev+3,off, + "Going to read byte %08x",nr); + if (!(ientry = psiconv_list_get(bytes,nr))) + goto ERROR2; + psiconv_debug(config,lev+3,off,"Byte value: %02x",*ientry); + input = *ientry; + ibits = 8; + nr ++; + } + bits = ibits + obits > colordepth?colordepth-obits:ibits; + output = output << bits; + output |= input & ((1 << bits) - 1); + input = input >> bits; + ibits -= bits; + obits += bits; + } + psiconv_debug(config,lev+2,off,"Pixel value: %08x",output); + if ((res = psiconv_list_add(*pixels,&output))) + goto ERROR2; + } + } + + psiconv_progress(config,lev,off, + "Converting bytes to pixels completed"); + return 0; + + +ERROR2: + psiconv_list_free(*pixels); +ERROR1: + psiconv_warn(config,lev+1,off,"Converting bytes to pixels failed"); + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + +int psiconv_pixel_data_to_floats (const psiconv_config config, int lev, + psiconv_u32 off, + const psiconv_pixel_ints pixels, + psiconv_pixel_floats_t *floats, + int colordepth, int color, + int redbits, int bluebits, int greenbits, + const psiconv_pixel_floats_t palet) +{ + int res = 0; + psiconv_u32 i; + psiconv_u32 *pixel; + + psiconv_progress(config,lev+1,off,"Going to convert pixels to floats"); + if (!((*floats).red = malloc(psiconv_list_length(pixels) * + sizeof(*(*floats).red)))) + goto ERROR1; + if (!((*floats).green = malloc(psiconv_list_length(pixels) * + sizeof(*(*floats).green)))) + goto ERROR2; + if (!((*floats).blue = malloc(psiconv_list_length(pixels) * + sizeof(*(*floats).blue)))) + goto ERROR3; + (*floats).length = psiconv_list_length(pixels); + + for (i = 0; i < psiconv_list_length(pixels); i++) { + if (!(pixel = psiconv_list_get(pixels,i))) + goto ERROR4; + psiconv_progress(config,lev+2,off, "Handling pixel %04x (%04x)",i,*pixel); + if (!palet.length) { + if (color) { + (*floats).blue[i] = (*pixel & ((1 << bluebits) - 1)) / + (1 << bluebits); + (*floats).green[i] = ((*pixel >> bluebits) & ((1 << greenbits) - 1)) / + (1 << greenbits); + (*floats).red[i] = ((*pixel >> (bluebits+greenbits)) & + ((1 << redbits) - 1)) / (1 << redbits); + } else { + (*floats).red[i] = (*floats).green[i] = + (*floats).blue[i] = *pixel / (1 << colordepth); + } + } else { + if (*pixel >= palet.length) { + psiconv_warn(config,lev+2,off, + "Invalid palet color found (using color 0x00)"); + (*floats).red[i] = palet.red[0]; + (*floats).green[i] = palet.green[0]; + (*floats).blue[i] = palet.blue[0]; + } else { + (*floats).red[i] = palet.red[*pixel]; + (*floats).green[i] = palet.green[*pixel]; + (*floats).blue[i] = palet.blue[*pixel]; + } + } + psiconv_debug(config,lev+2,off, "Pixel: Red (%f), green (%f), blue (%f)", + (*floats).red[i],(*floats).green[i],(*floats).blue[i]); + } + psiconv_progress(config,lev+1,off,"Finished converting pixels to floats"); + return 0; + +ERROR4: + free((*floats).blue); +ERROR3: + free((*floats).green); +ERROR2: + free((*floats).red); +ERROR1: + psiconv_warn(config,lev+1,off,"Converting pixels to floats failed"); + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + + +