--- psiconv/trunk/lib/psiconv/generate_image.c 2003/11/27 20:55:01 175 +++ psiconv/trunk/lib/psiconv/generate_image.c 2003/12/02 19:47:47 176 @@ -44,7 +44,8 @@ static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels, int xsize,int ysize, const psiconv_pixel_floats_t data, - int colordepth, + int colordepth,int color, + int redbits,int greenbits,int bluebits, const psiconv_pixel_floats_t palet); static int psiconv_pixel_data_to_bytes(const psiconv_config config, psiconv_pixel_bytes *bytes, int xsize, @@ -53,6 +54,9 @@ static int psiconv_encode_rle8(const psiconv_config config, const psiconv_pixel_bytes plain_bytes, psiconv_pixel_bytes *encoded_bytes); +static int psiconv_encode_rle12(const psiconv_config config, + const psiconv_pixel_bytes plain_bytes, + psiconv_pixel_bytes *encoded_bytes); static int psiconv_encode_rle16(const psiconv_config config, const psiconv_pixel_bytes plain_bytes, psiconv_pixel_bytes *encoded_bytes); @@ -60,32 +64,8 @@ const psiconv_pixel_bytes plain_bytes, psiconv_pixel_bytes *encoded_bytes); -#define PALET_GREY_2_LEN 4 -float palet_grey_2_rgb[PALET_GREY_2_LEN] = {0.0/3, 1.0/3, 2.0/3, 3.0/3}; -#define PALET_GREY_4_LEN 16 -float palet_grey_4_rgb[PALET_GREY_4_LEN] = - { 0.0/15, 1.0/15, 2.0/15, 3.0/15, - 4.0/15, 5.0/15, 6.0/15, 7.0/15, - 8.0/15, 9.0/15, 10.0/15, 11.0/15, - 12.0/15, 13.0/15, 14.0/15, 15.0/15}; #define PALET_NONE_LEN 0 -psiconv_pixel_floats_t palet_grey_2 = - { - PALET_GREY_2_LEN, - (float *) palet_grey_2_rgb, - (float *) palet_grey_2_rgb, - (float *) palet_grey_2_rgb - }; - -psiconv_pixel_floats_t palet_grey_4 = - { - PALET_GREY_4_LEN, - (float *) palet_grey_4_rgb, - (float *) palet_grey_4_rgb, - (float *) palet_grey_4_rgb - }; - psiconv_pixel_floats_t palet_none = { PALET_NONE_LEN, @@ -94,6 +74,245 @@ NULL }; +#define PALET_COLOR_4_LEN 16 +float palet_color_4_red[PALET_COLOR_4_LEN] = + { 0x00/256.0, 0x55/256.0, 0x80/256.0, 0x80/256.0, /* 0x00 */ + 0x00/256.0, 0xff/256.0, 0x00/256.0, 0xff/256.0, /* 0x04 */ + 0xff/256.0, 0x00/256.0, 0x00/256.0, 0x80/256.0, /* 0x08 */ + 0x00/256.0, 0x00/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */ + }; + +float palet_color_4_green[PALET_COLOR_4_LEN] = + { 0x00/256.0, 0x55/256.0, 0x00/256.0, 0x80/256.0, /* 0x00 */ + 0x80/256.0, 0x00/256.0, 0xff/256.0, 0xff/256.0, /* 0x04 */ + 0x00/256.0, 0xff/256.0, 0xff/256.0, 0x00/256.0, /* 0x08 */ + 0x00/256.0, 0x80/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */ + }; + +float palet_color_4_blue[PALET_COLOR_4_LEN] = + { 0x00/256.0, 0x55/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x04 */ + 0xff/256.0, 0x00/256.0, 0xff/256.0, 0x80/256.0, /* 0x08 */ + 0x80/256.0, 0x80/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */ + }; + +psiconv_pixel_floats_t palet_color_4 = + { + PALET_COLOR_4_LEN, + palet_color_4_red, + palet_color_4_green, + palet_color_4_blue, + }; + +#define PALET_COLOR_8_LEN 256 +float palet_color_8_red[PALET_COLOR_8_LEN] = + { 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x00 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x04 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x08 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x0c */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x10 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x14 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x18 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x1c */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x20 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x24 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x28 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x2c */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x30 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x34 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x38 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x3c */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x40 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x44 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x48 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x4c */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x50 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x54 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x58 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x5c */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x60 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x64 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x68 */ + 0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */ + 0x77/256.0, 0x11/256.0, 0x22/256.0, 0x44/256.0, /* 0x70 */ + 0x55/256.0, 0x77/256.0, 0x00/256.0, 0x00/256.0, /* 0x74 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x78 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x7c */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x80 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x84 */ + 0x00/256.0, 0x00/256.0, 0x88/256.0, 0xaa/256.0, /* 0x88 */ + 0xbb/256.0, 0xdd/256.0, 0xee/256.0, 0x88/256.0, /* 0x8c */ + 0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x94 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x98 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x9c */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xa0 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xa4 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xa8 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xac */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xb0 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xb4 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xb8 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xbc */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xc0 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xc4 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xc8 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xcc */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xd0 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xd4 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xd8 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xdc */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xe0 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xe4 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xe8 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xec */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xf0 */ + 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xf4 */ + 0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xf8 */ + 0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0 /* 0xfc */ + }; + +float palet_color_8_green[PALET_COLOR_8_LEN] = + { 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */ + 0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x04 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x08 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x0c */ + 0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x10 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x14 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x18 */ + 0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x1c */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x20 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x24 */ + 0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x28 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x2c */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x30 */ + 0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x34 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x38 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x3c */ + 0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x40 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x44 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x48 */ + 0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x4c */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x50 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x54 */ + 0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x58 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x5c */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x60 */ + 0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x64 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x68 */ + 0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */ + 0x77/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x70 */ + 0x00/256.0, 0x00/256.0, 0x11/256.0, 0x22/256.0, /* 0x74 */ + 0x44/256.0, 0x55/256.0, 0x77/256.0, 0x00/256.0, /* 0x78 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x7c */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x80 */ + 0x00/256.0, 0x88/256.0, 0xaa/256.0, 0xbb/256.0, /* 0x84 */ + 0xdd/256.0, 0xee/256.0, 0x00/256.0, 0x00/256.0, /* 0x88 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x88/256.0, /* 0x8c */ + 0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x94 */ + 0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x98 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x9c */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xa0 */ + 0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xa4 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa8 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xac */ + 0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xb0 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xb4 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0xb8 */ + 0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0xbc */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0xc0 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xc4 */ + 0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xc8 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xcc */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd0 */ + 0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xd4 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xd8 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0xdc */ + 0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0xe0 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0xe4 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xe8 */ + 0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xec */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xf0 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xf4 */ + 0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xf8 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xfc */ + }; + +float palet_color_8_blue[PALET_COLOR_8_LEN] = + { 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x04 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x08 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x0c */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x10 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x14 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x18 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x1c */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x20 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x24 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x28 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x2c */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x30 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x34 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x38 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x3c */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x40 */ + 0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x44 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x48 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x4c */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x50 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x54 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x58 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x5c */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x60 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x64 */ + 0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x68 */ + 0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */ + 0x77/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x70 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x74 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x11/256.0, /* 0x78 */ + 0x22/256.0, 0x44/256.0, 0x55/256.0, 0x77/256.0, /* 0x7c */ + 0x88/256.0, 0xaa/256.0, 0xbb/256.0, 0xdd/256.0, /* 0x80 */ + 0xee/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x84 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x88 */ + 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x88/256.0, /* 0x8c */ + 0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x94 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x98 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x9c */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa0 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa4 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa8 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xac */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xb0 */ + 0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xb4 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xb8 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xbc */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc0 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc4 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc8 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xcc */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd0 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd4 */ + 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd8 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xdc */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe0 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe4 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe8 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xec */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf0 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf4 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf8 */ + 0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xfc */ + }; + +psiconv_pixel_floats_t palet_color_8 = + { + PALET_COLOR_8_LEN, + palet_color_8_red, + palet_color_8_green, + palet_color_8_blue, + }; int psiconv_write_paint_data_section(const psiconv_config config, psiconv_buffer buf, @@ -106,6 +325,45 @@ psiconv_list bytes,bytes_rle; psiconv_u8 *byteptr,encoding; + /* First, we check whether we can cope with the current configuration. + If not, we stop at once */ + if ((config->colordepth != 2) && (config->colordepth != 4) && + (config->colordepth != 8) && (config->colordepth != 12) && + (config->colordepth != 16) && (config->colordepth != 24)) { + psiconv_warn(config,0,psiconv_buffer_length(buf), + "Unsupported color depth (%d); try 2, 4, 8, 16 or 24", + config->colordepth); + res = -PSICONV_E_GENERATE; + goto ERROR1; + } + + if ((config->color) && + (config->bluebits || config->redbits || config->greenbits) && + (config->bluebits+config->redbits+config->greenbits!=config->colordepth)) { + psiconv_warn(config,0,psiconv_buffer_length(buf), + "Sum of red (%d), green (%d) and blue (%d) bits should be " + "equal to the color depth (%d)", + config->redbits,config->greenbits,config->bluebits, + config->colordepth); + res = -PSICONV_E_GENERATE; + goto ERROR1; + } + + if (config->color && + !(config->redbits || config->greenbits || config->bluebits) && + (config->colordepth != 4) && (config->colordepth != 8)) { + psiconv_warn(config,0,psiconv_buffer_length(buf), + "Current color depth (%d) has no palet associated with it", + config->colordepth); + res = -PSICONV_E_GENERATE; + goto ERROR1; + } + + if (config->color || (config->colordepth != 2)) + psiconv_warn(config,0,psiconv_buffer_length(buf), + "All image types except 2-bit greyscale are experimental!"); + + if (!value) { psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section"); res = -PSICONV_E_GENERATE; @@ -117,17 +375,20 @@ floats.blue = value->blue; floats.length = value->xsize * value->ysize; - switch (config->colordepth) { - default: - case 2: palet = (config->color?palet_none:palet_grey_2); - break; - case 4: palet = (config->color?palet_none:palet_grey_4); - break; - } + palet = palet_none; + if ((config->color) && (config->redbits == 0) && (config->greenbits == 0) &&\ + (config->bluebits == 0)) + switch (config->colordepth) { + case 4: palet = palet_color_4; break; + case 8: palet = palet_color_8; break; + default: palet = palet_none; break; + } if ((res = psiconv_collect_pixel_data(&ints,value->xsize, value->ysize,floats, - config->colordepth,palet))) + config->colordepth,config->color, + config->redbits,config->greenbits, + config->bluebits,palet))) goto ERROR1; if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize, @@ -135,15 +396,40 @@ goto ERROR2; - encoding = 0x00; - if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle))) - goto ERROR3; - if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) { - encoding = 0x01; - psiconv_list_free(bytes); - bytes = bytes_rle; - } else { - bytes_rle = NULL; + switch (config->colordepth) { + case 2: + case 4: + case 8: + encoding = 0x01; + if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle))) + goto ERROR3; + break; + case 12: + encoding = 0x02; + if ((res = psiconv_encode_rle12(config,bytes,&bytes_rle))) + goto ERROR3; + break; + case 16: + encoding = 0x03; + if ((res = psiconv_encode_rle16(config,bytes,&bytes_rle))) + goto ERROR3; + break; + case 24: + encoding = 0x04; + if ((res = psiconv_encode_rle24(config,bytes,&bytes_rle))) + goto ERROR3; + break; + default: + encoding = 0x00; + } + if (encoding) { + if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) { + psiconv_list_free(bytes); + bytes = bytes_rle; + } else { + psiconv_list_free(bytes_rle); + encoding = 0x00; + } } if ((res = psiconv_write_u32(config,buf, @@ -160,8 +446,6 @@ if ((res = psiconv_write_length(config,buf,value->pic_ysize))) goto ERROR3; colordepth = config->colordepth; - if ((colordepth != 2) && colordepth != 4) - colordepth = 2; if ((res = psiconv_write_u32(config,buf,colordepth))) goto ERROR3; if ((res = psiconv_write_u32(config,buf,(config->color?1:0)))) @@ -197,19 +481,19 @@ now. For greyscale pictures, just use the palet. */ int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize, const psiconv_pixel_floats_t data, - int colordepth, + int colordepth,int color, + int redbits,int bluebits,int greenbits, const psiconv_pixel_floats_t palet) { int res,x,y,i; psiconv_u32 index,pixel; - float p_red,p_green,p_blue,mult,dist,new_dist; + float p_red,p_green,p_blue,dist,new_dist; if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) { res = -PSICONV_E_NOMEM; goto ERROR1; } - mult = 1 << colordepth; for (y = 0; y < ysize; y++) { for (x = 0; x < xsize; x++) { index = y*xsize+x; @@ -217,9 +501,14 @@ p_green = data.green[index]; p_blue = data.blue[index]; if (!palet.length) { - pixel = (((psiconv_u32) (p_red*mult+0.5)) << (2*colordepth)) + - (((psiconv_u32) (p_green*mult+0.5)) << colordepth) + - ((psiconv_u32) (p_blue*mult+0.5)); + if (color) + pixel = (((psiconv_u32) (p_red * (1 << redbits) + 0.5)) + << (greenbits+bluebits)) + + (((psiconv_u32) (p_green * (1 << greenbits) + 0.5)) + << bluebits) + + ((psiconv_u32) (p_blue * (1 << bluebits) + 0.5)); + else + pixel = (p_red + p_green + p_blue)/3.0 * (1 << colordepth); } else { dist = 4; /* Max distance is 3, so this is safe */ pixel = -1; @@ -332,6 +621,10 @@ return res; } +/* RLE8 encoding: + Marker bytes followed by one or more data bytes. + Marker value 0x00-0x7f: repeat the next data byte (marker+1) times + Marker value 0xff-0x80: (0x100-marker) data bytes follow */ int psiconv_encode_rle8(const psiconv_config config, const psiconv_pixel_bytes plain_bytes, psiconv_pixel_bytes *encoded_bytes) @@ -415,6 +708,115 @@ return res; } +/* RLE12 encoding: + Word based. The 12 least significant bits contain the pixel colors. + the 4 most signigicant bits are the number of repetitions minus 1 */ +int psiconv_encode_rle12(const psiconv_config config, + const psiconv_pixel_bytes plain_bytes, + psiconv_pixel_bytes *encoded_bytes) +{ + typedef psiconv_list psiconv_word_data; /* of psiconv_u16 */ + psiconv_word_data data; + int res,i,len,location; + psiconv_u16 *word_entry,*word_next; + psiconv_u16 word_data; + psiconv_u8 byte_temp; + psiconv_u8 *byte_entry; + + + /* First extract the 12-bit values to encode */ + if (!(data = psiconv_list_new(sizeof(psiconv_u16)))) { + res = -PSICONV_E_NOMEM; + goto ERROR1; + } + + for (i = 0; i < psiconv_list_length(plain_bytes); i++) { + if (!(byte_entry = psiconv_list_get(plain_bytes,i))) { + res = -PSICONV_E_NOMEM; + goto ERROR2; + } + location = 0; + if (location == 0) { + word_data = *byte_entry; + location ++; + } else if (location == 1) { + word_data = (word_data << 4) + (*byte_entry & 0x0f); + if ((res = psiconv_list_add(data,&word_data))) + goto ERROR2; + word_data = *byte_entry >> 4; + location ++; + } else { + word_data = (word_data << 8) + *byte_entry; + if ((res = psiconv_list_add(data,&word_data))) + goto ERROR2; + location = 0; + } + } + + if (!(*encoded_bytes = psiconv_list_new(sizeof(psiconv_u8)))) { + res = -PSICONV_E_NOMEM; + goto ERROR2; + } + + for (i = 0; i < psiconv_list_length(data);) { + if (!(word_entry = psiconv_list_get(data,i))) { + res = -PSICONV_E_NOMEM; + goto ERROR3; + } + + if (!(word_next = psiconv_list_get(data,i+1))) { + res = -PSICONV_E_NOMEM; + goto ERROR3; + } + + if (i == psiconv_list_length(data) - 2) { + byte_temp = *word_entry && 0xff; + if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) + goto ERROR3; + byte_temp = *word_entry >> 8; + if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) + goto ERROR3; + byte_temp = *word_next && 0xff; + if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) + goto ERROR3; + byte_temp = *word_next >> 8; + if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) + goto ERROR3; + i += 2; + } + + len = 0; + while ((*word_entry == *word_next) && (len < 16) && + (i+len+1 < psiconv_list_length(data))) { + len ++; + if (!(word_next = psiconv_list_get(data,i+len))) { + res = -PSICONV_E_NOMEM; + goto ERROR3; + } + } + + byte_temp = *word_entry && 0xff; + if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) + goto ERROR3; + byte_temp = (*word_entry >> 8) + ((len - 1) << 4); + if ((res = psiconv_list_add(*encoded_bytes,&byte_temp))) + goto ERROR3; + i += len; + } + return 0; + +ERROR3: + psiconv_list_free(*encoded_bytes); +ERROR2: + psiconv_list_free(data); +ERROR1: + return res; +} + +/* RLE16 encoding: + Marker bytes followed by one or more data words. + Marker value 0x00-0x7f: repeat the next data word (marker+1) times + Marker value 0xff-0x80: (0x100-marker) data words follow */ int psiconv_encode_rle16(const psiconv_config config, const psiconv_pixel_bytes plain_bytes, psiconv_pixel_bytes *encoded_bytes) @@ -527,6 +929,10 @@ return res; } +/* RLE24 encoding: + Marker bytes followed by one or more data byte-triplets. + Marker value 0x00-0x7f: repeat the next data byte-triplets (marker+1) times + Marker value 0xff-0x80: (0x100-marker) data byte-triplets follow */ int psiconv_encode_rle24(const psiconv_config config, const psiconv_pixel_bytes plain_bytes, psiconv_pixel_bytes *encoded_bytes)