/[public]/psiconv/trunk/lib/psiconv/generate_image.c
ViewVC logotype

Diff of /psiconv/trunk/lib/psiconv/generate_image.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 175 Revision 184
22#include "compat.h" 22#include "compat.h"
23 23
24#include "generate_routines.h" 24#include "generate_routines.h"
25#include "error.h" 25#include "error.h"
26#include "list.h" 26#include "list.h"
27#include "image.h"
27 28
28#ifdef DMALLOC 29#ifdef DMALLOC
29#include <dmalloc.h> 30#include <dmalloc.h>
30#endif 31#endif
31 32
32typedef psiconv_list psiconv_pixel_bytes; /* psiconv_u8 */
33
34typedef psiconv_list psiconv_pixel_ints; /* of psiconv_u32 */
35
36typedef struct psiconv_pixel_float_s
37{
38 psiconv_u32 length;
39 float *red;
40 float *green;
41 float *blue;
42} psiconv_pixel_floats_t;
43 33
44static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels, 34static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,
45 int xsize,int ysize, 35 int xsize,int ysize,
46 const psiconv_pixel_floats_t data, 36 const psiconv_pixel_floats_t data,
47 int colordepth, 37 int colordepth,int color,
38 int redbits,int greenbits,int bluebits,
48 const psiconv_pixel_floats_t palet); 39 const psiconv_pixel_floats_t palet);
49static int psiconv_pixel_data_to_bytes(const psiconv_config config, 40static int psiconv_pixel_data_to_bytes(const psiconv_config config,
50 psiconv_pixel_bytes *bytes, int xsize, 41 psiconv_pixel_bytes *bytes, int xsize,
51 int ysize, const psiconv_pixel_ints pixels, 42 int ysize, const psiconv_pixel_ints pixels,
52 int colordepth); 43 int colordepth);
53static int psiconv_encode_rle8(const psiconv_config config, 44static int psiconv_encode_rle8(const psiconv_config config,
54 const psiconv_pixel_bytes plain_bytes, 45 const psiconv_pixel_bytes plain_bytes,
55 psiconv_pixel_bytes *encoded_bytes); 46 psiconv_pixel_bytes *encoded_bytes);
47static int psiconv_encode_rle12(const psiconv_config config,
48 const psiconv_pixel_bytes plain_bytes,
49 psiconv_pixel_bytes *encoded_bytes);
56static int psiconv_encode_rle16(const psiconv_config config, 50static int psiconv_encode_rle16(const psiconv_config config,
57 const psiconv_pixel_bytes plain_bytes, 51 const psiconv_pixel_bytes plain_bytes,
58 psiconv_pixel_bytes *encoded_bytes); 52 psiconv_pixel_bytes *encoded_bytes);
59static int psiconv_encode_rle24(const psiconv_config config, 53static int psiconv_encode_rle24(const psiconv_config config,
60 const psiconv_pixel_bytes plain_bytes, 54 const psiconv_pixel_bytes plain_bytes,
61 psiconv_pixel_bytes *encoded_bytes); 55 psiconv_pixel_bytes *encoded_bytes);
62 56
63#define PALET_GREY_2_LEN 4
64float palet_grey_2_rgb[PALET_GREY_2_LEN] = {0.0/3, 1.0/3, 2.0/3, 3.0/3};
65#define PALET_GREY_4_LEN 16
66float palet_grey_4_rgb[PALET_GREY_4_LEN] =
67 { 0.0/15, 1.0/15, 2.0/15, 3.0/15,
68 4.0/15, 5.0/15, 6.0/15, 7.0/15,
69 8.0/15, 9.0/15, 10.0/15, 11.0/15,
70 12.0/15, 13.0/15, 14.0/15, 15.0/15};
71#define PALET_NONE_LEN 0
72
73psiconv_pixel_floats_t palet_grey_2 =
74 {
75 PALET_GREY_2_LEN,
76 (float *) palet_grey_2_rgb,
77 (float *) palet_grey_2_rgb,
78 (float *) palet_grey_2_rgb
79 };
80
81psiconv_pixel_floats_t palet_grey_4 =
82 {
83 PALET_GREY_4_LEN,
84 (float *) palet_grey_4_rgb,
85 (float *) palet_grey_4_rgb,
86 (float *) palet_grey_4_rgb
87 };
88
89psiconv_pixel_floats_t palet_none =
90 {
91 PALET_NONE_LEN,
92 NULL,
93 NULL,
94 NULL
95 };
96
97
98int psiconv_write_paint_data_section(const psiconv_config config, 57int psiconv_write_paint_data_section(const psiconv_config config,
99 psiconv_buffer buf, 58 psiconv_buffer buf, int lev,
100 const psiconv_paint_data_section value, 59 const psiconv_paint_data_section value,
101 int is_clipart) 60 int is_clipart)
102{ 61{
103 int res,colordepth,i; 62 int res,colordepth,i;
104 psiconv_pixel_ints ints; 63 psiconv_pixel_ints ints;
105 psiconv_pixel_floats_t floats,palet; 64 psiconv_pixel_floats_t floats,palet;
106 psiconv_list bytes,bytes_rle; 65 psiconv_list bytes,bytes_rle;
107 psiconv_u8 *byteptr,encoding; 66 psiconv_u8 *byteptr,encoding;
108 67
68 psiconv_progress(config,lev,0,"Writing paint data section");
69
70 /* First, we check whether we can cope with the current configuration.
71 If not, we stop at once */
72 if ((config->colordepth != 2) && (config->colordepth != 4) &&
73 (config->colordepth != 8) && (config->colordepth != 12) &&
74 (config->colordepth != 16) && (config->colordepth != 24)) {
75 psiconv_error(config,0,psiconv_buffer_length(buf),
76 "Unsupported color depth (%d); try 2, 4, 8, 16 or 24",
77 config->colordepth);
78 res = -PSICONV_E_GENERATE;
79 goto ERROR1;
80 }
81
82 if ((config->color) &&
83 (config->bluebits || config->redbits || config->greenbits) &&
84 (config->bluebits+config->redbits+config->greenbits!=config->colordepth)) {
85 psiconv_error(config,0,psiconv_buffer_length(buf),
86 "Sum of red (%d), green (%d) and blue (%d) bits should be "
87 "equal to the color depth (%d)",
88 config->redbits,config->greenbits,config->bluebits,
89 config->colordepth);
90 res = -PSICONV_E_GENERATE;
91 goto ERROR1;
92 }
93
94 if (config->color &&
95 !(config->redbits || config->greenbits || config->bluebits) &&
96 (config->colordepth != 4) && (config->colordepth != 8)) {
97 psiconv_error(config,0,psiconv_buffer_length(buf),
98 "Current color depth (%d) has no palet associated with it",
99 config->colordepth);
100 res = -PSICONV_E_GENERATE;
101 goto ERROR1;
102 }
103
104 if (config->color || (config->colordepth != 2))
105 psiconv_warn(config,0,psiconv_buffer_length(buf),
106 "All image types except 2-bit greyscale are experimental!");
107
108
109 if (!value) { 109 if (!value) {
110 psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section"); 110 psiconv_error(config,0,psiconv_buffer_length(buf),"Null paint data section");
111 res = -PSICONV_E_GENERATE; 111 res = -PSICONV_E_GENERATE;
112 goto ERROR1; 112 goto ERROR1;
113 } 113 }
114 114
115 floats.red = value->red; 115 floats.red = value->red;
116 floats.green = value->green; 116 floats.green = value->green;
117 floats.blue = value->blue; 117 floats.blue = value->blue;
118 floats.length = value->xsize * value->ysize; 118 floats.length = value->xsize * value->ysize;
119 119
120 palet = psiconv_palet_none;
121 if ((config->color) && (config->redbits == 0) && (config->greenbits == 0) &&
122 (config->bluebits == 0))
120 switch (config->colordepth) { 123 switch (config->colordepth) {
121 default: 124 case 4: palet = psiconv_palet_color_4; break;
122 case 2: palet = (config->color?palet_none:palet_grey_2); 125 case 8: palet = psiconv_palet_color_8; break;
123 break; 126 default: palet = psiconv_palet_none; break;
124 case 4: palet = (config->color?palet_none:palet_grey_4);
125 break;
126 } 127 }
127 128
128 if ((res = psiconv_collect_pixel_data(&ints,value->xsize, 129 if ((res = psiconv_collect_pixel_data(&ints,value->xsize,
129 value->ysize,floats, 130 value->ysize,floats,
130 config->colordepth,palet))) 131 config->colordepth,config->color,
132 config->redbits,config->greenbits,
133 config->bluebits,palet))) {
134 psiconv_error(config,lev,0,"Error collecting pixel data");
131 goto ERROR1; 135 goto ERROR1;
136 }
132 137
133 if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize, 138 if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize,
134 ints,config->colordepth))) 139 ints,config->colordepth))) {
140 psiconv_error(config,lev,0,"Error translating pixel data to bytes");
135 goto ERROR2; 141 goto ERROR2;
142 }
136 143
137 144
145 switch (config->colordepth) {
146 case 2:
147 case 4:
148 case 8:
138 encoding = 0x00; 149 encoding = 0x01;
139 if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle))) 150 if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle))) {
151 psiconv_error(config,lev,0,"Error encoding RLE8");
140 goto ERROR3; 152 goto ERROR3;
153 }
154 break;
155 case 12:
156 encoding = 0x02;
157 if ((res = psiconv_encode_rle12(config,bytes,&bytes_rle))) {
158 psiconv_error(config,lev,0,"Error encoding RLE12");
159 goto ERROR3;
160 }
161 break;
162 case 16:
163 encoding = 0x03;
164 if ((res = psiconv_encode_rle16(config,bytes,&bytes_rle))) {
165 psiconv_error(config,lev,0,"Error encoding RLE16");
166 goto ERROR3;
167 }
168 break;
169 case 24:
170 encoding = 0x04;
171 if ((res = psiconv_encode_rle24(config,bytes,&bytes_rle))) {
172 psiconv_error(config,lev,0,"Error encoding RLE24");
173 goto ERROR3;
174 }
175 break;
176 default:
177 encoding = 0x00;
178 }
179 if (encoding) {
141 if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) { 180 if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) {
142 encoding = 0x01;
143 psiconv_list_free(bytes); 181 psiconv_list_free(bytes);
144 bytes = bytes_rle; 182 bytes = bytes_rle;
145 } else { 183 } else {
146 bytes_rle = NULL; 184 psiconv_list_free(bytes_rle);
185 encoding = 0x00;
147 } 186 }
187 }
148 188
149 if ((res = psiconv_write_u32(config,buf, 189 if ((res = psiconv_write_u32(config,buf,lev+1,
150 0x28+psiconv_list_length(bytes)))) 190 0x28+psiconv_list_length(bytes))))
151 goto ERROR3; 191 goto ERROR3;
152 if ((res = psiconv_write_u32(config,buf,0x28))) 192 if ((res = psiconv_write_u32(config,buf,lev+1,0x28)))
153 goto ERROR3; 193 goto ERROR3;
154 if ((res = psiconv_write_u32(config,buf,value->xsize))) 194 if ((res = psiconv_write_u32(config,buf,lev+1,value->xsize)))
155 goto ERROR3; 195 goto ERROR3;
156 if ((res = psiconv_write_u32(config,buf,value->ysize))) 196 if ((res = psiconv_write_u32(config,buf,lev+1,value->ysize)))
157 goto ERROR3; 197 goto ERROR3;
158 if ((res = psiconv_write_length(config,buf,value->pic_xsize))) 198 if ((res = psiconv_write_length(config,buf,lev+1,value->pic_xsize)))
159 goto ERROR3; 199 goto ERROR3;
160 if ((res = psiconv_write_length(config,buf,value->pic_ysize))) 200 if ((res = psiconv_write_length(config,buf,lev+1,value->pic_ysize)))
161 goto ERROR3; 201 goto ERROR3;
162 colordepth = config->colordepth; 202 colordepth = config->colordepth;
163 if ((colordepth != 2) && colordepth != 4)
164 colordepth = 2;
165 if ((res = psiconv_write_u32(config,buf,colordepth))) 203 if ((res = psiconv_write_u32(config,buf,lev+1,colordepth)))
166 goto ERROR3; 204 goto ERROR3;
167 if ((res = psiconv_write_u32(config,buf,(config->color?1:0)))) 205 if ((res = psiconv_write_u32(config,buf,lev+1,(config->color?1:0))))
168 goto ERROR3; 206 goto ERROR3;
169 if ((res = psiconv_write_u32(config,buf,0))) 207 if ((res = psiconv_write_u32(config,buf,lev+1,0)))
170 goto ERROR3; 208 goto ERROR3;
171 if ((res = psiconv_write_u32(config,buf,encoding))) 209 if ((res = psiconv_write_u32(config,buf,lev+1,encoding)))
172 goto ERROR3; 210 goto ERROR3;
173 if (is_clipart) { 211 if (is_clipart) {
174 if ((res = psiconv_write_u32(config,buf,0xffffffff))) 212 if ((res = psiconv_write_u32(config,buf,lev+1,0xffffffff)))
175 goto ERROR3; 213 goto ERROR3;
176 if ((res = psiconv_write_u32(config,buf,0x00000044))) 214 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000044)))
177 goto ERROR3; 215 goto ERROR3;
178 } 216 }
179 for (i = 0; i < psiconv_list_length(bytes); i++) { 217 for (i = 0; i < psiconv_list_length(bytes); i++) {
180 if (!(byteptr = psiconv_list_get(bytes,i))) 218 if (!(byteptr = psiconv_list_get(bytes,i)))
181 goto ERROR3; 219 goto ERROR3;
182 if ((res = psiconv_write_u8(config,buf,*byteptr))) 220 if ((res = psiconv_write_u8(config,buf,lev+1,*byteptr)))
183 goto ERROR3; 221 goto ERROR3;
184 } 222 }
185 223
186ERROR3: 224ERROR3:
187 psiconv_list_free(bytes); 225 psiconv_list_free(bytes);
195 The palet is optional; without it, we just use the 233 The palet is optional; without it, we just use the
196 colordepth. With a large palet this is not very fast, but it will do for 234 colordepth. With a large palet this is not very fast, but it will do for
197 now. For greyscale pictures, just use the palet. */ 235 now. For greyscale pictures, just use the palet. */
198int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize, 236int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize,
199 const psiconv_pixel_floats_t data, 237 const psiconv_pixel_floats_t data,
200 int colordepth, 238 int colordepth,int color,
239 int redbits,int bluebits,int greenbits,
201 const psiconv_pixel_floats_t palet) 240 const psiconv_pixel_floats_t palet)
202{ 241{
203 int res,x,y,i; 242 int res,x,y,i;
204 psiconv_u32 index,pixel; 243 psiconv_u32 index,pixel;
205 float p_red,p_green,p_blue,mult,dist,new_dist; 244 float p_red,p_green,p_blue,dist,new_dist;
206 245
207 if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) { 246 if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) {
208 res = -PSICONV_E_NOMEM; 247 res = -PSICONV_E_NOMEM;
209 goto ERROR1; 248 goto ERROR1;
210 } 249 }
211 250
212 mult = 1 << colordepth;
213 for (y = 0; y < ysize; y++) { 251 for (y = 0; y < ysize; y++) {
214 for (x = 0; x < xsize; x++) { 252 for (x = 0; x < xsize; x++) {
215 index = y*xsize+x; 253 index = y*xsize+x;
216 p_red = data.red[index]; 254 p_red = data.red[index];
217 p_green = data.green[index]; 255 p_green = data.green[index];
218 p_blue = data.blue[index]; 256 p_blue = data.blue[index];
219 if (!palet.length) { 257 if (!palet.length) {
220 pixel = (((psiconv_u32) (p_red*mult+0.5)) << (2*colordepth)) + 258 if (color)
221 (((psiconv_u32) (p_green*mult+0.5)) << colordepth) + 259 pixel = (((psiconv_u32) (p_red * (1 << redbits) + 0.5))
260 << (greenbits+bluebits)) +
261 (((psiconv_u32) (p_green * (1 << greenbits) + 0.5))
262 << bluebits) +
222 ((psiconv_u32) (p_blue*mult+0.5)); 263 ((psiconv_u32) (p_blue * (1 << bluebits) + 0.5));
264 else
265 pixel = (p_red + p_green + p_blue)/3.0 * (1 << colordepth);
223 } else { 266 } else {
224 dist = 4; /* Max distance is 3, so this is safe */ 267 dist = 4; /* Max distance is 3, so this is safe */
225 pixel = -1; 268 pixel = -1;
226 for (i = 0; i < palet.length; i++) { 269 for (i = 0; i < palet.length; i++) {
227 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) + 270 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) +
258 psiconv_u32 *pixelptr; 301 psiconv_u32 *pixelptr;
259 int inputbitsleft,outputbitnr,bitsfit,outputbytenr; 302 int inputbitsleft,outputbitnr,bitsfit,outputbytenr;
260 303
261 304
262 if (!bytes) { 305 if (!bytes) {
263 psiconv_warn(config,0,0,"NULL pixel data"); 306 psiconv_error(config,0,0,"NULL pixel data");
264 res = -PSICONV_E_GENERATE; 307 res = -PSICONV_E_GENERATE;
265 goto ERROR1; 308 goto ERROR1;
266 } 309 }
267 if (!pixels) { 310 if (!pixels) {
268 psiconv_warn(config,0,0,"NULL pixel data"); 311 psiconv_error(config,0,0,"NULL pixel data");
269 res = -PSICONV_E_GENERATE; 312 res = -PSICONV_E_GENERATE;
270 goto ERROR1; 313 goto ERROR1;
271 } 314 }
272 if (psiconv_list_length(pixels) != xsize * ysize) { 315 if (psiconv_list_length(pixels) != xsize * ysize) {
273 psiconv_warn(config,0,0,"Pixel number is not correct"); 316 psiconv_error(config,0,0,"Pixel number is not correct");
274 res = -PSICONV_E_GENERATE; 317 res = -PSICONV_E_GENERATE;
275 goto ERROR1; 318 goto ERROR1;
276 } 319 }
277 320
278 if (!(*bytes = psiconv_list_new(sizeof(psiconv_u8)))) { 321 if (!(*bytes = psiconv_list_new(sizeof(psiconv_u8)))) {
285 outputbyte = 0; 328 outputbyte = 0;
286 for (y = 0; y < ysize; y++) { 329 for (y = 0; y < ysize; y++) {
287 outputbytenr = 0; 330 outputbytenr = 0;
288 for (x = 0; x < xsize; x++) { 331 for (x = 0; x < xsize; x++) {
289 if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) { 332 if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) {
290 psiconv_warn(config,0,0,"Massive internal corruption"); 333 psiconv_error(config,0,0,"Massive internal corruption");
291 res = -PSICONV_E_NOMEM; 334 res = -PSICONV_E_NOMEM;
292 goto ERROR2; 335 goto ERROR2;
293 } 336 }
294 inputbitsleft = colordepth; 337 inputbitsleft = colordepth;
295 inputdata = *pixelptr; 338 inputdata = *pixelptr;
330 psiconv_list_free(*bytes); 373 psiconv_list_free(*bytes);
331ERROR1: 374ERROR1:
332 return res; 375 return res;
333} 376}
334 377
378/* RLE8 encoding:
379 Marker bytes followed by one or more data bytes.
380 Marker value 0x00-0x7f: repeat the next data byte (marker+1) times
381 Marker value 0xff-0x80: (0x100-marker) data bytes follow */
335int psiconv_encode_rle8(const psiconv_config config, 382int psiconv_encode_rle8(const psiconv_config config,
336 const psiconv_pixel_bytes plain_bytes, 383 const psiconv_pixel_bytes plain_bytes,
337 psiconv_pixel_bytes *encoded_bytes) 384 psiconv_pixel_bytes *encoded_bytes)
338{ 385{
339 int res,i,j,len; 386 int res,i,j,len;
362 goto ERROR2; 409 goto ERROR2;
363 if ((res = psiconv_list_add(*encoded_bytes,next))) 410 if ((res = psiconv_list_add(*encoded_bytes,next)))
364 goto ERROR2; 411 goto ERROR2;
365 i +=2; 412 i +=2;
366 } else if (*next == *entry) { 413 } else if (*next == *entry) {
367 len = 0; 414 len = 1;
368 while ((*next == *entry) && 415 while ((*next == *entry) &&
369 (i+len + 1 < psiconv_list_length(plain_bytes)) && 416 (i+len + 2 < psiconv_list_length(plain_bytes)) &&
370 len < 0x80) { 417 len < 0x80) {
371 len ++; 418 len ++;
372 if (!(next = psiconv_list_get(plain_bytes,i+len))) { 419 if (!(next = psiconv_list_get(plain_bytes,i+len))) {
373 res = -PSICONV_E_NOMEM; 420 res = -PSICONV_E_NOMEM;
374 goto ERROR2; 421 goto ERROR2;
413 psiconv_list_free(*encoded_bytes); 460 psiconv_list_free(*encoded_bytes);
414ERROR1: 461ERROR1:
415 return res; 462 return res;
416} 463}
417 464
465/* RLE12 encoding:
466 Word based. The 12 least significant bits contain the pixel colors.
467 the 4 most signigicant bits are the number of repetitions minus 1 */
468int psiconv_encode_rle12(const psiconv_config config,
469 const psiconv_pixel_bytes plain_bytes,
470 psiconv_pixel_bytes *encoded_bytes)
471{
472 typedef psiconv_list psiconv_word_data; /* of psiconv_u16 */
473 psiconv_word_data data;
474 int res,i,len,location;
475 psiconv_u16 *word_entry,*word_next;
476 psiconv_u16 word_data;
477 psiconv_u8 byte_temp;
478 psiconv_u8 *byte_entry;
479
480
481 /* First extract the 12-bit values to encode */
482 if (!(data = psiconv_list_new(sizeof(psiconv_u16)))) {
483 res = -PSICONV_E_NOMEM;
484 goto ERROR1;
485 }
486
487 for (i = 0; i < psiconv_list_length(plain_bytes); i++) {
488 if (!(byte_entry = psiconv_list_get(plain_bytes,i))) {
489 res = -PSICONV_E_NOMEM;
490 goto ERROR2;
491 }
492 location = 0;
493 if (location == 0) {
494 word_data = *byte_entry;
495 location ++;
496 } else if (location == 1) {
497 word_data = (word_data << 4) + (*byte_entry & 0x0f);
498 if ((res = psiconv_list_add(data,&word_data)))
499 goto ERROR2;
500 word_data = *byte_entry >> 4;
501 location ++;
502 } else {
503 word_data = (word_data << 8) + *byte_entry;
504 if ((res = psiconv_list_add(data,&word_data)))
505 goto ERROR2;
506 location = 0;
507 }
508 }
509
510 if (!(*encoded_bytes = psiconv_list_new(sizeof(psiconv_u8)))) {
511 res = -PSICONV_E_NOMEM;
512 goto ERROR2;
513 }
514
515 for (i = 0; i < psiconv_list_length(data);) {
516 if (!(word_entry = psiconv_list_get(data,i))) {
517 res = -PSICONV_E_NOMEM;
518 goto ERROR3;
519 }
520
521 if (!(word_next = psiconv_list_get(data,i+1))) {
522 res = -PSICONV_E_NOMEM;
523 goto ERROR3;
524 }
525
526 if (i == psiconv_list_length(data) - 2) {
527 byte_temp = *word_entry && 0xff;
528 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
529 goto ERROR3;
530 byte_temp = *word_entry >> 8;
531 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
532 goto ERROR3;
533 byte_temp = *word_next && 0xff;
534 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
535 goto ERROR3;
536 byte_temp = *word_next >> 8;
537 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
538 goto ERROR3;
539 i += 2;
540 }
541
542 len = 0;
543 while ((*word_entry == *word_next) && (len < 16) &&
544 (i+len+1 < psiconv_list_length(data))) {
545 len ++;
546 if (!(word_next = psiconv_list_get(data,i+len))) {
547 res = -PSICONV_E_NOMEM;
548 goto ERROR3;
549 }
550 }
551
552 byte_temp = *word_entry && 0xff;
553 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
554 goto ERROR3;
555 byte_temp = (*word_entry >> 8) + ((len - 1) << 4);
556 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
557 goto ERROR3;
558 i += len;
559 }
560 return 0;
561
562ERROR3:
563 psiconv_list_free(*encoded_bytes);
564ERROR2:
565 psiconv_list_free(data);
566ERROR1:
567 return res;
568}
569
570/* RLE16 encoding:
571 Marker bytes followed by one or more data words.
572 Marker value 0x00-0x7f: repeat the next data word (marker+1) times
573 Marker value 0xff-0x80: (0x100-marker) data words follow */
418int psiconv_encode_rle16(const psiconv_config config, 574int psiconv_encode_rle16(const psiconv_config config,
419 const psiconv_pixel_bytes plain_bytes, 575 const psiconv_pixel_bytes plain_bytes,
420 psiconv_pixel_bytes *encoded_bytes) 576 psiconv_pixel_bytes *encoded_bytes)
421{ 577{
422 int res,i,j,len; 578 int res,i,j,len;
525 psiconv_list_free(*encoded_bytes); 681 psiconv_list_free(*encoded_bytes);
526ERROR1: 682ERROR1:
527 return res; 683 return res;
528} 684}
529 685
686/* RLE24 encoding:
687 Marker bytes followed by one or more data byte-triplets.
688 Marker value 0x00-0x7f: repeat the next data byte-triplets (marker+1) times
689 Marker value 0xff-0x80: (0x100-marker) data byte-triplets follow */
530int psiconv_encode_rle24(const psiconv_config config, 690int psiconv_encode_rle24(const psiconv_config config,
531 const psiconv_pixel_bytes plain_bytes, 691 const psiconv_pixel_bytes plain_bytes,
532 psiconv_pixel_bytes *encoded_bytes) 692 psiconv_pixel_bytes *encoded_bytes)
533{ 693{
534 int res,i,j,len; 694 int res,i,j,len;
671 return res; 831 return res;
672} 832}
673 833
674 834
675int psiconv_write_sketch_section(const psiconv_config config, 835int psiconv_write_sketch_section(const psiconv_config config,
676 psiconv_buffer buf, 836 psiconv_buffer buf, int lev,
677 const psiconv_sketch_section value) 837 const psiconv_sketch_section value)
678{ 838{
679 int res; 839 int res;
680 840
841 psiconv_progress(config,lev,0,"Writing sketch section");
681 if (!value) { 842 if (!value) {
682 psiconv_warn(config,0,0,"NULL sketch section"); 843 psiconv_error(config,0,0,"NULL sketch section");
683 res = -PSICONV_E_GENERATE; 844 res = -PSICONV_E_GENERATE;
684 goto ERROR1; 845 goto ERROR1;
685 } 846 }
686 847
687 if ((res = psiconv_write_u16(config,buf,value->displayed_xsize))) 848 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_xsize)))
688 goto ERROR1; 849 goto ERROR1;
689 if ((res = psiconv_write_u16(config,buf,value->displayed_ysize))) 850 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_ysize)))
690 goto ERROR1; 851 goto ERROR1;
691 if ((res = psiconv_write_u16(config,buf,value->picture_data_x_offset))) 852 if ((res = psiconv_write_u16(config,buf,lev+1,value->picture_data_x_offset)))
692 goto ERROR1; 853 goto ERROR1;
693 if ((res = psiconv_write_u16(config,buf,value->picture_data_y_offset))) 854 if ((res = psiconv_write_u16(config,buf,lev+1,value->picture_data_y_offset)))
694 goto ERROR1; 855 goto ERROR1;
695 if ((res = psiconv_write_u16(config,buf,value->displayed_size_x_offset))) 856 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_size_x_offset)))
696 goto ERROR1; 857 goto ERROR1;
697 if ((res = psiconv_write_u16(config,buf,value->displayed_size_y_offset))) 858 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_size_y_offset)))
698 goto ERROR1; 859 goto ERROR1;
699 if ((res = psiconv_write_u16(config,buf,value->form_xsize))) 860 if ((res = psiconv_write_u16(config,buf,lev+1,value->form_xsize)))
700 goto ERROR1; 861 goto ERROR1;
701 if ((res = psiconv_write_u16(config,buf,value->form_ysize))) 862 if ((res = psiconv_write_u16(config,buf,lev+1,value->form_ysize)))
702 goto ERROR1; 863 goto ERROR1;
703 if ((res = psiconv_write_u16(config,buf,0x0000))) 864 if ((res = psiconv_write_u16(config,buf,lev+1,0x0000)))
704 goto ERROR1; 865 goto ERROR1;
705 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,0))) 866 if ((res = psiconv_write_paint_data_section(config,buf,lev+1,value->picture,0)))
706 goto ERROR1; 867 goto ERROR1;
707 if ((res = psiconv_write_u16(config,buf,value->magnification_x * 0x03e8))) 868 if ((res = psiconv_write_u16(config,buf,lev+1,value->magnification_x * 0x03e8)))
708 goto ERROR1; 869 goto ERROR1;
709 if ((res = psiconv_write_u16(config,buf,value->magnification_y * 0x03e8))) 870 if ((res = psiconv_write_u16(config,buf,lev+1,value->magnification_y * 0x03e8)))
710 goto ERROR1; 871 goto ERROR1;
711 if ((res = psiconv_write_u32(config,buf,value->cut_left * 0x0c * 872 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_left * 0x0c *
712 value->displayed_xsize))) 873 value->displayed_xsize)))
713 goto ERROR1; 874 goto ERROR1;
714 if ((res = psiconv_write_u32(config,buf,value->cut_right * 0x0c * 875 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_right * 0x0c *
715 value->displayed_xsize))) 876 value->displayed_xsize)))
716 goto ERROR1; 877 goto ERROR1;
717 if ((res = psiconv_write_u32(config,buf,value->cut_top * 0x0c * 878 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_top * 0x0c *
718 value->displayed_ysize))) 879 value->displayed_ysize)))
719 goto ERROR1; 880 goto ERROR1;
720 if ((res = psiconv_write_u32(config,buf,value->cut_bottom * 0x0c * 881 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_bottom * 0x0c *
721 value->displayed_ysize))) 882 value->displayed_ysize)))
722 goto ERROR1; 883 goto ERROR1;
723 884
724ERROR1: 885ERROR1:
725 return res; 886 return res;
726} 887}
727 888
728int psiconv_write_clipart_section(const psiconv_config config, 889int psiconv_write_clipart_section(const psiconv_config config,
729 psiconv_buffer buf, 890 psiconv_buffer buf, int lev,
730 const psiconv_clipart_section value) 891 const psiconv_clipart_section value)
731{ 892{
732 int res; 893 int res;
733 894
734 895 psiconv_progress(config,lev,0,"Writing clipart section");
735 if (!value) { 896 if (!value) {
736 psiconv_warn(config,0,psiconv_buffer_length(buf), 897 psiconv_error(config,0,psiconv_buffer_length(buf),
737 "NULL Clipart Section"); 898 "NULL Clipart Section");
738 res = -PSICONV_E_GENERATE; 899 res = -PSICONV_E_GENERATE;
739 goto ERROR; 900 goto ERROR;
740 } 901 }
741 if ((res = psiconv_write_u32(config,buf,PSICONV_ID_CLIPART_ITEM))) 902 if ((res = psiconv_write_u32(config,buf,lev+1,PSICONV_ID_CLIPART_ITEM)))
742 goto ERROR; 903 goto ERROR;
743 if ((res = psiconv_write_u32(config,buf,0x00000002))) 904 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000002)))
744 goto ERROR; 905 goto ERROR;
745 if ((res = psiconv_write_u32(config,buf,0x00000000))) 906 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000000)))
746 goto ERROR; 907 goto ERROR;
747 if ((res = psiconv_write_u32(config,buf,0x00000000))) 908 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000000)))
748 goto ERROR; 909 goto ERROR;
749 if ((res = psiconv_write_u32(config,buf,0x0000000C))) 910 if ((res = psiconv_write_u32(config,buf,lev+1,0x0000000C)))
750 goto ERROR; 911 goto ERROR;
751 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,1))) 912 if ((res = psiconv_write_paint_data_section(config,buf,lev+1,value->picture,1)))
752 goto ERROR; 913 goto ERROR;
753 914
754ERROR: 915ERROR:
755 return res; 916 return res;
756} 917}
757 918
758int psiconv_write_jumptable_section(const psiconv_config config, 919int psiconv_write_jumptable_section(const psiconv_config config,
759 psiconv_buffer buf, 920 psiconv_buffer buf, int lev,
760 const psiconv_jumptable_section value) 921 const psiconv_jumptable_section value)
761{ 922{
762 int res,i; 923 int res,i;
763 psiconv_u32 *offset_ptr; 924 psiconv_u32 *offset_ptr;
764 925
926 psiconv_progress(config,lev,0,"Writing jumptable section");
765 927
766 if (!value) { 928 if (!value) {
767 psiconv_warn(config,0,psiconv_buffer_length(buf), 929 psiconv_error(config,0,psiconv_buffer_length(buf),
768 "NULL Jumptable Section"); 930 "NULL Jumptable Section");
769 res = -PSICONV_E_GENERATE; 931 res = -PSICONV_E_GENERATE;
770 goto ERROR; 932 goto ERROR;
771 } 933 }
772 if ((res = psiconv_write_u32(config,buf,psiconv_list_length(value)))) 934 if ((res = psiconv_write_u32(config,buf,lev+1,psiconv_list_length(value))))
773 goto ERROR; 935 goto ERROR;
774 for (i = 0; i < psiconv_list_length(value); i++) { 936 for (i = 0; i < psiconv_list_length(value); i++) {
775 if (!(offset_ptr = psiconv_list_get(value,i))) { 937 if (!(offset_ptr = psiconv_list_get(value,i))) {
776 psiconv_warn(config,0,psiconv_buffer_length(buf), 938 psiconv_error(config,0,psiconv_buffer_length(buf),
777 "Massive memory corruption"); 939 "Massive memory corruption");
778 res = -PSICONV_E_NOMEM; 940 res = -PSICONV_E_NOMEM;
779 goto ERROR; 941 goto ERROR;
780 } 942 }
781 if ((res = psiconv_write_offset(config,buf,*offset_ptr))) 943 if ((res = psiconv_write_offset(config,buf,lev+1,*offset_ptr)))
782 goto ERROR; 944 goto ERROR;
783 } 945 }
784 946
785ERROR: 947ERROR:
786 return res; 948 return res;

Legend:
Removed from v.175  
changed lines
  Added in v.184

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26