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

Annotation of /psiconv/trunk/lib/psiconv/parse_image.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 230 - (hide annotations)
Wed Feb 25 20:56:43 2004 UTC (20 years, 1 month ago) by frodo
File MIME type: text/plain
File size: 34541 byte(s)
(Frodo) Modify debugging level

The noise from parsing pictures was ridiculous. Now you have to edit the C
code and #define LOUD to have it shout at you like that.

1 frodo 10 /*
2     parse_image.c - Part of psiconv, a PSION 5 file formats converter
3 frodo 196 Copyright (c) 1999-2004 Frodo Looijaard <frodol@dds.nl>
4 frodo 10
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18     */
19    
20     #include "config.h"
21 frodo 71 #include "compat.h"
22    
23 frodo 10 #include <stdlib.h>
24    
25     #include "parse_routines.h"
26 frodo 71 #include "error.h"
27 frodo 178 #include "image.h"
28 frodo 10
29 frodo 142 #ifdef DMALLOC
30     #include <dmalloc.h>
31     #endif
32    
33 frodo 230 /* Extreme debugging info */
34     #undef LOUD
35    
36 frodo 178 static int psiconv_decode_rle8 (const psiconv_config config, int lev,
37     psiconv_u32 off,
38     const psiconv_pixel_bytes encoded,
39     psiconv_pixel_bytes *decoded);
40 frodo 142
41 frodo 179 static int psiconv_decode_rle12 (const psiconv_config config, int lev,
42     psiconv_u32 off,
43     const psiconv_pixel_bytes encoded,
44     psiconv_pixel_bytes *decoded);
45    
46     static int psiconv_decode_rle16 (const psiconv_config config, int lev,
47     psiconv_u32 off,
48     const psiconv_pixel_bytes encoded,
49     psiconv_pixel_bytes *decoded);
50    
51     static int psiconv_decode_rle24 (const psiconv_config config, int lev,
52     psiconv_u32 off,
53     const psiconv_pixel_bytes encoded,
54     psiconv_pixel_bytes *decoded);
55    
56 frodo 178 static int psiconv_bytes_to_pixel_data(const psiconv_config config,
57     int lev, psiconv_u32 off,
58     const psiconv_pixel_bytes bytes,
59     psiconv_pixel_ints *pixels,
60     int colordepth, int xsize, int ysize);
61    
62     static int psiconv_pixel_data_to_floats (const psiconv_config config, int lev,
63     psiconv_u32 off,
64     const psiconv_pixel_ints pixels,
65     psiconv_pixel_floats_t *floats,
66     int colordepth, int color,
67     int redbits, int bluebits, int greenbits,
68     const psiconv_pixel_floats_t palet);
69    
70    
71    
72 frodo 168 int psiconv_parse_jumptable_section(const psiconv_config config,
73     const psiconv_buffer buf,int lev,
74 frodo 42 psiconv_u32 off, int *length,
75     psiconv_jumptable_section *result)
76 frodo 12 {
77     int res = 0;
78     int len = 0;
79     psiconv_u32 listlen,temp;
80     int i;
81    
82 frodo 168 psiconv_progress(config,lev+1,off+len,"Going to read the jumptable section");
83 frodo 64 if (!((*result) = psiconv_list_new(sizeof(psiconv_u32))))
84     goto ERROR1;
85 frodo 12
86 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the list length");
87     listlen = psiconv_read_u32(config,buf,lev+2,off+len,&res);
88 frodo 65 if (res)
89 frodo 64 goto ERROR2;
90 frodo 168 psiconv_debug(config,lev+2,off+len,"List length: %08x",listlen);
91 frodo 12 len += 4;
92    
93 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the list");
94 frodo 12 for (i = 0; i < listlen; i++) {
95 frodo 168 temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
96 frodo 65 if (res)
97 frodo 64 goto ERROR2;
98     if ((res = psiconv_list_add(*result,&temp)))
99     goto ERROR2;
100 frodo 168 psiconv_debug(config,lev+3,off+len,"Offset: %08x",temp);
101 frodo 12 len += 4;
102     }
103    
104     if (length)
105     *length = len;
106    
107 frodo 168 psiconv_progress(config,lev+1,off+len-1,"End of jumptable section "
108 frodo 13 "(total length: %08x)", len);
109 frodo 12
110 frodo 64 return 0;
111    
112     ERROR2:
113     psiconv_list_free(*result);
114     ERROR1:
115 frodo 184 psiconv_error(config,lev+1,off,"Reading of Jumptable Section failed");
116 frodo 64 if (length)
117     *length = 0;
118     if (!res)
119     return -PSICONV_E_NOMEM;
120     else
121     return res;
122 frodo 12 }
123    
124 frodo 168 int psiconv_parse_paint_data_section(const psiconv_config config,
125     const psiconv_buffer buf,int lev,
126 frodo 45 psiconv_u32 off, int *length,int isclipart,
127 frodo 10 psiconv_paint_data_section *result)
128     {
129     int res = 0;
130     int len = 0;
131 frodo 179 psiconv_u32 size,offset,picsize,temp,datasize,color,
132     redbits,bluebits,greenbits;
133     psiconv_u8 byte;
134     int leng,i;
135 frodo 25 psiconv_u32 bits_per_pixel,compression;
136 frodo 179 psiconv_pixel_bytes bytes,decoded;
137     psiconv_pixel_ints pixels;
138     psiconv_pixel_floats_t floats,palet;
139 frodo 10
140 frodo 168 psiconv_progress(config,lev+1,off,"Going to read a paint data section");
141 frodo 64 if (!((*result) = malloc(sizeof(**result))))
142     goto ERROR1;
143 frodo 10
144 frodo 179 if (!(bytes = psiconv_list_new(sizeof(psiconv_u8))))
145     goto ERROR2;
146    
147 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read section size");
148     size = psiconv_read_u32(config,buf,lev+2,off+len,&res);
149 frodo 64 if (res)
150 frodo 179 goto ERROR3;
151 frodo 168 psiconv_debug(config,lev+2,off+len,"Section size: %08x",size);
152 frodo 10 len += 4;
153    
154 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read pixel data offset");
155     offset = psiconv_read_u32(config,buf,lev+2,off+len,&res);
156 frodo 64 if (res)
157 frodo 179 goto ERROR3;
158 frodo 13 if (offset != 0x28) {
159 frodo 184 psiconv_error(config,lev+2,off+len,
160 frodo 10 "Paint data section data offset has unexpected value");
161 frodo 168 psiconv_debug(config,lev+2,off+len,
162 frodo 10 "Data offset: read %08x, expected %08x",offset,0x28);
163 frodo 12 res = -1;
164 frodo 10 }
165     len += 4;
166    
167 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read picture X size");
168     (*result)->xsize = psiconv_read_u32(config,buf,lev+2,off+len,&res);
169 frodo 64 if (res)
170 frodo 179 goto ERROR3;
171 frodo 168 psiconv_debug(config,lev+2,off+len,"Picture X size: %08x:",(*result)->xsize);
172 frodo 10 len += 4;
173    
174 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read picture Y size");
175     (*result)->ysize = psiconv_read_u32(config,buf,lev+2,off+len,&res);
176 frodo 64 if (res)
177 frodo 179 goto ERROR3;
178 frodo 168 psiconv_debug(config,lev+2,off+len,"Picture Y size: %08x:",(*result)->ysize);
179 frodo 10 len += 4;
180    
181 frodo 25 picsize = (*result)->ysize * (*result)->xsize;
182 frodo 10
183 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the real picture x size");
184     (*result)->pic_xsize = psiconv_read_length(config,buf,lev+2,off+len,&leng,&res);
185 frodo 64 if (res)
186 frodo 179 goto ERROR3;
187 frodo 168 psiconv_debug(config,lev+2,off+len,"Picture x size: %f",(*result)->pic_xsize);
188 frodo 25 len += leng;
189    
190 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the real picture y size");
191     (*result)->pic_ysize = psiconv_read_length(config,buf,lev+2,off+len,&leng,&res);
192 frodo 64 if (res)
193 frodo 179 goto ERROR3;
194 frodo 168 psiconv_debug(config,lev+2,off+len,"Picture y size: %f",(*result)->pic_ysize);
195 frodo 25 len += leng;
196    
197 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the number of bits per pixel");
198     bits_per_pixel=psiconv_read_u32(config,buf,lev+2,off+len,&res);
199 frodo 64 if (res)
200 frodo 179 goto ERROR3;
201 frodo 168 psiconv_debug(config,lev+2,off+len,"Bits per pixel: %d",bits_per_pixel);
202 frodo 25 len += 4;
203    
204 frodo 179 psiconv_progress(config,lev+2,off+len,
205     "Going to read whether this is a colour or greyscale picture");
206     color = psiconv_read_u32(config,buf,lev+2,off+len,&res);
207     if (res)
208     goto ERROR3;
209     if ((color != 0) && (color != 1)) {
210     psiconv_warn(config,lev+2,off+len,
211     "Paint data section unknown color type (ignored)");
212     psiconv_debug(config,lev+2,off+len,
213     "Color: read %08x, expected %08x or %08x",color,0,1);
214     color = 1;
215     } else {
216     psiconv_debug(config,lev+2,off+len,"Color: %08x (%s picture)",
217     color,(color?"color":"greyscale"));
218 frodo 10 }
219 frodo 179 len += 4;
220    
221     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
222     if (res)
223     goto ERROR3;
224     if (temp != 00) {
225     psiconv_warn(config,lev+2,off+len,
226     "Paint data section prologue has unknown values (ignored)");
227     psiconv_debug(config,lev+2,off+len,
228     "read %08x, expected %08x",temp, 0x00);
229     }
230     len += 4;
231 frodo 25
232 frodo 168 psiconv_progress(config,lev+2,off+len,
233 frodo 25 "Going to read whether RLE compression is used");
234 frodo 168 compression=psiconv_read_u32(config,buf,lev+2,off+len,&res);
235 frodo 64 if (res)
236 frodo 179 goto ERROR3;
237     if (compression > 4) {
238 frodo 168 psiconv_warn(config,lev+2,off+len,"Paint data section has unknown "
239 frodo 25 "compression type, assuming RLE");
240 frodo 168 psiconv_debug(config,lev+2,off+len,"Read compression type %d",compression);
241 frodo 179 compression = 0;
242 frodo 25 }
243 frodo 179 psiconv_debug(config,lev+2,off+len,"Compression: %s",
244     compression == 4?"RLE24":compression == 3?"RLE16":
245     compression == 2?"RLE12":compression == 1?"RLE8":"none");
246 frodo 45 len += 4;
247 frodo 10
248 frodo 45 if (isclipart) {
249 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read an unknown long");
250     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
251 frodo 64 if (res)
252 frodo 179 goto ERROR3;
253 frodo 45 if (temp != 0xffffffff) {
254 frodo 168 psiconv_warn(config,lev+2,off+len,
255 frodo 64 "Paint data section prologue has unknown values (ignoring)");
256 frodo 168 psiconv_debug(config,lev+2,off+len,
257 frodo 179 "Read %08x, expected %08x",temp, 0xffffffff);
258 frodo 45 }
259     len += 4;
260 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read a second unknown long");
261     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
262 frodo 64 if (res)
263 frodo 179 goto ERROR3;
264 frodo 45 if (temp != 0x44) {
265 frodo 168 psiconv_warn(config,lev+2,off+len,
266 frodo 64 "Paint data section prologue has unknown values (ignoring)");
267 frodo 168 psiconv_debug(config,lev+2,off+len,
268 frodo 179 "read %08x, expected %08x",temp, 0x44);
269 frodo 45 }
270     len += 4;
271     }
272    
273 frodo 10 len = offset;
274     datasize = size - len;
275 frodo 45 if (isclipart)
276     len += 8;
277 frodo 10
278 frodo 179 if (color || (bits_per_pixel != 2))
279     psiconv_warn(config,lev+2,off+len,
280     "All image types except 2-bit greyscale are experimental!");
281    
282 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the pixel data");
283 frodo 179 for (i = 0; i < datasize; i++) {
284     byte = psiconv_read_u8(config,buf,lev+2,off+len+i,&res);
285 frodo 230 #ifdef LOUD
286 frodo 179 psiconv_debug(config,lev+2,off+len+i,
287     "Pixel byte %04x of %04x has value %02x",
288     i,datasize,byte);
289 frodo 230 #endif
290 frodo 179 if (res)
291     goto ERROR3;
292     psiconv_list_add(bytes,&byte);
293 frodo 10 }
294 frodo 179 len += datasize;
295 frodo 25
296 frodo 179 switch(compression) {
297     case 1:
298     if ((res = psiconv_decode_rle8(config,lev+2,off+len,bytes,&decoded)))
299     goto ERROR3;
300     psiconv_list_free(bytes);
301     bytes = decoded;
302     break;
303     case 2:
304     if ((psiconv_decode_rle12(config,lev+2,off+len,bytes,&decoded)))
305     goto ERROR3;
306     psiconv_list_free(bytes);
307     bytes = decoded;
308     break;
309     case 3:
310     if ((psiconv_decode_rle16(config,lev+2,off+len,bytes,&decoded)))
311     goto ERROR3;
312     psiconv_list_free(bytes);
313     bytes = decoded;
314     break;
315     case 4:
316     if ((psiconv_decode_rle24(config,lev+2,off+len,bytes,&decoded)))
317     goto ERROR3;
318     psiconv_list_free(bytes);
319     bytes = decoded;
320     break;
321 frodo 12 }
322    
323 frodo 179 if ((res = psiconv_bytes_to_pixel_data(config,lev+2,off+len,bytes,
324     &pixels,bits_per_pixel,
325     (*result)->xsize,(*result)->ysize)))
326     goto ERROR3;
327 frodo 10
328 frodo 179 /* Use some heuristics; things may get unexpected around here */
329     bluebits = redbits = greenbits = 0;
330     palet = psiconv_palet_none;
331     if (color) {
332     if (bits_per_pixel == 4)
333     palet = psiconv_palet_color_4;
334     else if (bits_per_pixel == 8)
335     palet = psiconv_palet_color_8;
336     else {
337     redbits = (bits_per_pixel+2) / 3;
338     greenbits = (bits_per_pixel+2) / 3;
339     bluebits = bits_per_pixel - redbits - greenbits;
340     }
341     }
342     if ((res = psiconv_pixel_data_to_floats(config,lev+2,off+len,pixels,
343     &floats,bits_per_pixel,color,
344     redbits,greenbits,bluebits,palet)))
345     goto ERROR4;
346    
347     (*result)->red = floats.red;
348     (*result)->green = floats.green;
349     (*result)->blue = floats.blue;
350    
351     psiconv_list_free(bytes);
352     psiconv_list_free(pixels);
353    
354    
355 frodo 10 if (length)
356     *length = len;
357    
358 frodo 179 psiconv_progress(config,lev,off+len-1,
359     "End of Paint Data Section (total length: %08x)", len);
360 frodo 10
361 frodo 179 return 0;
362 frodo 64
363     ERROR4:
364 frodo 179 psiconv_list_free(pixels);
365 frodo 64 ERROR3:
366 frodo 179 psiconv_list_free(bytes);
367 frodo 64 ERROR2:
368 frodo 179 free(*result);
369 frodo 64 ERROR1:
370 frodo 184 psiconv_error(config,lev+1,off,"Reading of Paint Data Section failed");
371 frodo 64 if (length)
372     *length = 0;
373     if (!res)
374     return -PSICONV_E_NOMEM;
375     else
376     return res;
377 frodo 10 }
378    
379 frodo 168 int psiconv_parse_sketch_section(const psiconv_config config,
380     const psiconv_buffer buf, int lev,
381 frodo 163 psiconv_u32 off, int *length,
382 frodo 24 psiconv_sketch_section *result)
383     {
384     int res=0;
385     int len=0;
386     psiconv_u32 temp;
387     int leng;
388    
389 frodo 168 psiconv_progress(config,lev+1,off,"Going to read the sketch section");
390 frodo 64 if (!(*result = malloc(sizeof(**result))))
391     goto ERROR1;
392 frodo 24
393 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the displayed hor. size");
394     (*result)->displayed_xsize = psiconv_read_u16(config,buf,lev+2,off + len,&res);
395 frodo 163 if (res)
396     goto ERROR2;
397 frodo 168 psiconv_debug(config,lev+2,off+len,"Displayed hor. size: %04x",
398 frodo 163 (*result)->displayed_xsize);
399     len += 0x02;
400 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read displayed ver. size");
401     (*result)->displayed_ysize = psiconv_read_u16(config,buf,lev+2,off + len,&res);
402 frodo 163 if (res)
403     goto ERROR2;
404 frodo 168 psiconv_debug(config,lev+2,off+len,"Displayed ver. size: %04x",
405 frodo 163 (*result)->displayed_ysize);
406     len += 0x02;
407 frodo 24
408 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the data hor. offset");
409     (*result)->picture_data_x_offset = psiconv_read_u16(config,buf,lev+2,off + len,
410 frodo 163 &res);
411     if (res)
412     goto ERROR2;
413 frodo 168 psiconv_debug(config,lev+2,off+len,"Data hor. offset: %04x",
414 frodo 163 (*result)->picture_data_x_offset);
415     len += 0x02;
416 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the data ver. offset");
417     (*result)->picture_data_y_offset = psiconv_read_u16(config,buf,lev+2,off + len,
418 frodo 163 &res);
419     if (res)
420     goto ERROR2;
421 frodo 168 psiconv_debug(config,lev+2,off+len,"Data ver. offset: %04x",
422 frodo 163 (*result)->picture_data_y_offset);
423     len += 0x02;
424    
425 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the displayed hor. offset");
426     (*result)->displayed_size_x_offset = psiconv_read_u16(config,buf,lev+2,off + len,
427 frodo 163 &res);
428     if (res)
429     goto ERROR2;
430 frodo 168 psiconv_debug(config,lev+2,off+len,"Displayed hor. offset: %04x",
431 frodo 163 (*result)->displayed_size_x_offset);
432     len += 0x02;
433 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the displayed ver. offset");
434     (*result)->displayed_size_y_offset = psiconv_read_u16(config,buf,lev+2,off + len,
435 frodo 163 &res);
436     if (res)
437     goto ERROR2;
438 frodo 168 psiconv_debug(config,lev+2,off+len,"Displayed ver. offset: %04x",
439 frodo 163 (*result)->displayed_size_y_offset);
440     len += 0x02;
441    
442 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the form hor. size");
443     (*result)->form_xsize = psiconv_read_u16(config,buf,lev+2,off + len,&res);
444 frodo 163 if (res)
445     goto ERROR2;
446 frodo 168 psiconv_debug(config,lev+2,off+len,"Form hor. size: %04x",
447 frodo 163 (*result)->form_xsize);
448     len += 0x02;
449 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read form ver. size");
450     (*result)->form_ysize = psiconv_read_u16(config,buf,lev+2,off + len,&res);
451 frodo 163 if (res)
452     goto ERROR2;
453 frodo 168 psiconv_debug(config,lev+2,off+len,"Form ver. size: %04x",
454 frodo 163 (*result)->form_ysize);
455     len += 0x02;
456    
457 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to skip 1 word of zeros");
458     temp = psiconv_read_u16(config,buf,lev+2,off+len,&res);
459 frodo 163 if (res)
460     goto ERROR2;
461     if (temp != 0) {
462 frodo 168 psiconv_warn(config,lev+2,off+len,
463 frodo 163 "Unexpected value in sketch section preamble (ignored)");
464 frodo 168 psiconv_debug(config,lev+2,off+len,"Read %04x, expected %04x",
465 frodo 163 temp,0);
466 frodo 24 }
467 frodo 163 off += 0x02;
468 frodo 24
469 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the picture data");
470     if ((res = psiconv_parse_paint_data_section(config,buf,lev+2,off+len,&leng,0,
471 frodo 64 &((*result)->picture))))
472     goto ERROR2;
473 frodo 24 off += leng;
474    
475 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the hor. magnification");
476     (*result)->magnification_x = psiconv_read_u16(config,buf,lev+2,off+len,&res)/1000.0;
477 frodo 64 if (res)
478     goto ERROR3;
479 frodo 168 psiconv_debug(config,lev+2,off+len,"Form hor. magnification: %f",
480 frodo 24 (*result)->magnification_x);
481     len += 0x02;
482 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the ver. magnification");
483     (*result)->magnification_y = psiconv_read_u16(config,buf,lev+2,off+len,&res)/1000.0;
484 frodo 64 if (res)
485     goto ERROR3;
486 frodo 168 psiconv_debug(config,lev+2,off+len,"Form ver. magnification: %f",
487 frodo 24 (*result)->magnification_y);
488     len += 0x02;
489    
490 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the left cut");
491     temp = psiconv_read_u32(config,buf,lev+2,off + len,&res);
492 frodo 64 if (res)
493     goto ERROR3;
494 frodo 163 (*result)->cut_left = (temp * 6.0) / (*result)->displayed_xsize;
495 frodo 168 psiconv_debug(config,lev+2,off+len,"Left cut: raw %08x, real: %f",
496 frodo 24 temp,(*result)->cut_left);
497     len += 0x04;
498 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the right cut");
499     temp = psiconv_read_u32(config,buf,lev+2,off + len,&res);
500 frodo 64 if (res)
501     goto ERROR3;
502 frodo 163 (*result)->cut_right = (temp * 6.0) / (*result)->displayed_xsize;
503 frodo 168 psiconv_debug(config,lev+2,off+len,"Right cut: raw %08x, real: %f",
504 frodo 24 temp,(*result)->cut_right);
505     len += 0x04;
506 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the top cut");
507     temp = psiconv_read_u32(config,buf,lev+2,off + len,&res);
508 frodo 64 if (res)
509     goto ERROR3;
510 frodo 163 (*result)->cut_top = (temp * 6.0) / (*result)->displayed_ysize;
511 frodo 168 psiconv_debug(config,lev+2,off+len,"Top cut: raw %08x, real: %f",
512 frodo 24 temp,(*result)->cut_top);
513     len += 0x04;
514 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the bottom cut");
515     temp = psiconv_read_u32(config,buf,lev+2,off + len,&res);
516 frodo 64 if (res)
517     goto ERROR3;
518 frodo 163 (*result)->cut_bottom = (temp * 6.0) / (*result)->displayed_ysize;
519 frodo 168 psiconv_debug(config,lev+2,off+len,"Bottom cut: raw %08x, real: %f",
520 frodo 24 temp,(*result)->cut_bottom);
521     len += 0x04;
522    
523     if (length)
524     *length = len;
525    
526 frodo 168 psiconv_progress(config,lev,off+len-1,
527 frodo 24 "End of sketch section (total length: %08x)", len);
528    
529     return res;
530 frodo 64 ERROR3:
531     psiconv_free_paint_data_section((*result)->picture);
532     ERROR2:
533     free (*result);
534     ERROR1:
535 frodo 184 psiconv_error(config,lev+1,off,"Reading of Sketch Section failed");
536 frodo 64 if (length)
537     *length = 0;
538     if (!res)
539     return -PSICONV_E_NOMEM;
540     else
541     return res;
542 frodo 24 }
543    
544 frodo 43
545 frodo 168 int psiconv_parse_clipart_section(const psiconv_config config,
546     const psiconv_buffer buf,int lev,
547 frodo 43 psiconv_u32 off, int *length,
548     psiconv_clipart_section *result)
549     {
550     int res=0;
551     int len=0;
552     int leng;
553     psiconv_u32 temp;
554    
555 frodo 168 psiconv_progress(config,lev+1,off+len,"Going to read the clipart section");
556 frodo 64 if (!(*result = malloc(sizeof(**result))))
557     goto ERROR1;
558 frodo 43
559 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the section ID");
560     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
561 frodo 64 if (res)
562     goto ERROR2;
563 frodo 43 if (temp != PSICONV_ID_CLIPART_ITEM) {
564 frodo 168 psiconv_warn(config,lev+2,off+len,
565 frodo 64 "Unexpected value in clipart section preamble (ignored)");
566 frodo 168 psiconv_debug(config,lev+2,off+len,"Read %08x, expected %08x",temp,
567 frodo 43 PSICONV_ID_CLIPART_ITEM);
568     } else
569 frodo 168 psiconv_debug(config,lev+2,off+len,"Clipart ID: %08x", temp);
570 frodo 43 off += 4;
571    
572 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read an unknown long");
573     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
574 frodo 64 if (res)
575     goto ERROR2;
576 frodo 43 if (temp != 0x02) {
577 frodo 168 psiconv_warn(config,lev+2,off+len,
578 frodo 64 "Unexpected value in clipart section preamble (ignored)");
579 frodo 168 psiconv_debug(config,lev+2,off+len,"Read %08x, expected %08x",temp,
580 frodo 43 0x02);
581     } else
582 frodo 168 psiconv_debug(config,lev+2,off+len,"First unknown long: %08x", temp);
583 frodo 43 off += 4;
584    
585 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read a second unknown long");
586     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
587 frodo 64 if (res)
588     goto ERROR2;
589 frodo 43 if (temp != 0) {
590 frodo 168 psiconv_warn(config,lev+2,off+len,
591 frodo 64 "Unexpected value in clipart section preamble (ignored)");
592 frodo 168 psiconv_debug(config,lev+2,off+len,"Read %08x, expected %08x",temp, 0);
593 frodo 43 } else
594 frodo 168 psiconv_debug(config,lev+2,off+len,"Second unknown long: %08x", temp);
595 frodo 43 off += 4;
596    
597 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read a third unknown long");
598     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
599 frodo 64 if (res)
600     goto ERROR2;
601 frodo 43 if (temp != 0) {
602 frodo 168 psiconv_warn(config,lev+2,off+len,
603 frodo 64 "Unexpected value in clipart section preamble (ignored)");
604 frodo 168 psiconv_debug(config,lev+2,off+len,"Read %08x, expected %08x",temp, 0);
605 frodo 43 } else
606 frodo 168 psiconv_debug(config,lev+2,off+len,"Third unknown long: %08x", temp);
607 frodo 43 off += 4;
608    
609 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read a fourth unknown long");
610     temp = psiconv_read_u32(config,buf,lev+2,off+len,&res);
611 frodo 64 if (res)
612     goto ERROR2;
613 frodo 43 if ((temp != 0x0c) && (temp != 0x08)) {
614 frodo 168 psiconv_warn(config,lev+2,off+len,
615 frodo 64 "Unexpected value in clipart section preamble (ignored)");
616 frodo 168 psiconv_debug(config,lev+2,off+len,"Read %08x, expected %08x or %08x",temp,
617 frodo 43 0x0c, 0x08);
618     } else
619 frodo 168 psiconv_debug(config,lev+2,off+len,"Fourth unknown long: %08x", temp);
620 frodo 43 off += 4;
621    
622 frodo 168 psiconv_progress(config,lev+2,off+len,"Going to read the Paint Data Section");
623     if ((res = psiconv_parse_paint_data_section(config,buf,lev+2,off+len,&leng,1,
624 frodo 64 &((*result)->picture))))
625     goto ERROR2;
626 frodo 43 len += leng;
627    
628     if (length)
629     *length = len;
630    
631 frodo 168 psiconv_progress(config,lev,off+len-1,
632 frodo 43 "End of clipart section (total length: %08x)", len);
633 frodo 64 return 0;
634 frodo 43
635 frodo 64 ERROR2:
636     free (*result);
637     ERROR1:
638 frodo 184 psiconv_error(config,lev+1,off,"Reading of Font failed");
639 frodo 64 if (length)
640     *length = 0;
641     if (!res)
642     return -PSICONV_E_NOMEM;
643     else
644     return res;
645 frodo 43 }
646 frodo 178
647     int psiconv_decode_rle8 (const psiconv_config config, int lev, psiconv_u32 off,
648     const psiconv_pixel_bytes encoded,
649     psiconv_pixel_bytes *decoded)
650     {
651     int res=0;
652     psiconv_u8 *marker,*value;
653     int i,j;
654    
655     psiconv_progress(config,lev+1,off,"Going to decode the RLE8 encoding");
656     if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8))))
657     goto ERROR1;
658    
659     for (i = 0; i < psiconv_list_length(encoded);) {
660 frodo 230 #ifdef LOUD
661 frodo 178 psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i);
662 frodo 230 #endif
663 frodo 178 if (!(marker = psiconv_list_get(encoded,i)))
664     goto ERROR2;
665 frodo 230 #ifdef LOUD
666 frodo 178 psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker);
667 frodo 230 #endif
668 frodo 178 if (*marker < 0x80) {
669 frodo 230 #ifdef LOUD
670 frodo 178 psiconv_debug(config,lev+2,off,"Marker: repeat value byte %02x times",
671 frodo 230 *marker+1); */
672 frodo 178 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",i+1);
673 frodo 230 #endif
674 frodo 178 if (!(value = psiconv_list_get(encoded,i+1)))
675     goto ERROR2;
676 frodo 230 #ifdef LOUD
677     psiconv_debug(config,lev+2,off,"Value byte: %02x",*value);
678 frodo 179 psiconv_progress(config,lev+2,off,"Adding %02x pixels %02x",
679 frodo 178 *marker+1,*value);
680 frodo 230 #endif
681 frodo 178 for (j = 0; j < *marker + 1; j++)
682     if ((res = psiconv_list_add(*decoded,value)))
683     goto ERROR2;
684     i += 2;
685     } else {
686 frodo 230 #ifdef LOUD
687 frodo 178 psiconv_debug(config,lev+2,off,"Marker: %02x value bytes follow",
688     0x100 - *marker);
689 frodo 230 #endif
690 frodo 178 for (j = 0; j < (0x100 - *marker); j++) {
691 frodo 230 #ifdef LOUD
692 frodo 178 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",
693     i+j+1);
694 frodo 230 #endif
695 frodo 178 if (!(value = psiconv_list_get(encoded,i+j+1)))
696     goto ERROR2;
697 frodo 230 #ifdef LOUD
698     psiconv_debug(config,lev+2,off,"Value: %02x",*value);
699     #endif
700 frodo 178 if ((res = psiconv_list_add(*decoded,value)))
701     goto ERROR2;
702     }
703     i += (0x100 - *marker) + 1;
704     }
705     }
706     psiconv_progress(config,lev,off,
707     "End of RLE8 decoding process");
708     return 0;
709    
710     ERROR2:
711     psiconv_list_free(*decoded);
712     ERROR1:
713 frodo 184 psiconv_error(config,lev+1,off,"Decoding of RLE8 failed");
714 frodo 178 if (!res)
715     return -PSICONV_E_NOMEM;
716     else
717     return res;
718 frodo 179 }
719    
720     int psiconv_decode_rle12 (const psiconv_config config, int lev, psiconv_u32 off,
721     const psiconv_pixel_bytes encoded,
722     psiconv_pixel_bytes *decoded)
723     {
724     int res=0;
725     psiconv_u8 *value0,*value1;
726     psiconv_u32 value,repeat;
727     int i,j;
728    
729     psiconv_progress(config,lev+1,off,"Going to decode the RLE12 encoding");
730     if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8))))
731     goto ERROR1;
732    
733     for (i = 0; i < psiconv_list_length(encoded);) {
734     psiconv_progress(config,lev+2,off,"Going to read data word at %04x",i);
735     if (!(value0 = psiconv_list_get(encoded,i)))
736     goto ERROR2;
737     if (!(value1 = psiconv_list_get(encoded,i+1)))
738     goto ERROR2;
739     psiconv_debug(config,lev+2,off,"Data Word: %04x",*value0 + (*value1 << 8));
740     value = *value0 + ((*value1 & 0x0f) << 8);
741     repeat = (*value1 >> 4) + 1;
742     psiconv_progress(config,lev+2,off,"Adding %02x pixels %03x",
743     repeat,value);
744     for (j = 0; j < repeat; j ++)
745     if ((res = psiconv_list_add(*decoded,&value)))
746     goto ERROR2;
747     i += 2;
748     }
749     psiconv_progress(config,lev,off,
750     "End of RLE12 decoding process");
751     return 0;
752    
753     ERROR2:
754     psiconv_list_free(*decoded);
755     ERROR1:
756 frodo 184 psiconv_error(config,lev+1,off,"Decoding of RLE12 failed");
757 frodo 179 if (!res)
758     return -PSICONV_E_NOMEM;
759     else
760     return res;
761 frodo 178 }
762    
763 frodo 179 int psiconv_decode_rle16 (const psiconv_config config, int lev, psiconv_u32 off,
764     const psiconv_pixel_bytes encoded,
765     psiconv_pixel_bytes *decoded)
766     {
767     int res=0;
768     psiconv_u8 *marker,*value0,*value1;
769     psiconv_u32 value;
770     int i,j;
771    
772     psiconv_progress(config,lev+1,off,"Going to decode the RLE16 encoding");
773     if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8))))
774     goto ERROR1;
775    
776     for (i = 0; i < psiconv_list_length(encoded);) {
777     psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i);
778     if (!(marker = psiconv_list_get(encoded,i)))
779     goto ERROR2;
780     psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker);
781     if (*marker < 0x80) {
782     psiconv_debug(config,lev+2,off,"Marker: repeat value word %02x times",
783     *marker+1);
784     psiconv_progress(config,lev+2,off,"Going to read value word at %04x",i+1);
785     if (!(value0 = psiconv_list_get(encoded,i+1)))
786     goto ERROR2;
787     if (!(value1 = psiconv_list_get(encoded,i+2)))
788     goto ERROR2;
789     value = *value0 + (*value1 << 8);
790     psiconv_debug(config,lev+2,off,"Value word: %02x",value);
791     psiconv_progress(config,lev+2,off,"Adding %02x pixels %04x",
792     *marker+1,value);
793     for (j = 0; j < *marker + 1; j++)
794     if ((res = psiconv_list_add(*decoded,&value)))
795     goto ERROR2;
796     i += 3;
797     } else {
798     psiconv_debug(config,lev+2,off,"Marker: %02x value words follow",
799     0x100 - *marker);
800     for (j = 0; j < (0x100 - *marker); j++) {
801     psiconv_progress(config,lev+2,off,"Going to read value word at %04x",
802     i+j*2+1);
803     if (!(value0 = psiconv_list_get(encoded,i+j*2+1)))
804     goto ERROR2;
805     if (!(value1 = psiconv_list_get(encoded,i+j*2+2)))
806     goto ERROR2;
807     value = *value0 + (*value1 << 8);
808     psiconv_debug(config,lev+2,off,"Value: %04x",value);
809     if ((res = psiconv_list_add(*decoded,&value)))
810     goto ERROR2;
811     }
812     i += (0x100 - *marker)*2 + 1;
813     }
814     }
815     psiconv_progress(config,lev,off,
816     "End of RLE16 decoding process");
817     return 0;
818    
819     ERROR2:
820     psiconv_list_free(*decoded);
821     ERROR1:
822 frodo 184 psiconv_error(config,lev+1,off,"Decoding of RLE16 failed");
823 frodo 179 if (!res)
824     return -PSICONV_E_NOMEM;
825     else
826     return res;
827     }
828    
829     int psiconv_decode_rle24 (const psiconv_config config, int lev, psiconv_u32 off,
830     const psiconv_pixel_bytes encoded,
831     psiconv_pixel_bytes *decoded)
832     {
833     int res=0;
834     psiconv_u8 *marker,*value0,*value1,*value2;
835     psiconv_u32 value;
836     int i,j;
837    
838     psiconv_progress(config,lev+1,off,"Going to decode the RLE24 encoding");
839     if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8))))
840     goto ERROR1;
841    
842     for (i = 0; i < psiconv_list_length(encoded);) {
843     psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i);
844     if (!(marker = psiconv_list_get(encoded,i)))
845     goto ERROR2;
846     psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker);
847     if (*marker < 0x80) {
848     psiconv_debug(config,lev+2,off,"Marker: repeat value byte triplet %02x times",
849     *marker+1);
850     psiconv_progress(config,lev+2,off,"Going to read value byte triplet at %04x",i+1);
851     if (!(value0 = psiconv_list_get(encoded,i+1)))
852     goto ERROR2;
853     if (!(value1 = psiconv_list_get(encoded,i+2)))
854     goto ERROR2;
855     if (!(value2 = psiconv_list_get(encoded,i+3)))
856     goto ERROR2;
857     value = *value0 + (*value1 << 8) + (*value2 << 16);
858     psiconv_debug(config,lev+2,off,"Value byte triplet: %06x",value);
859     psiconv_progress(config,lev+2,off,"Adding %02x pixels %06x",
860     *marker+1,value);
861     for (j = 0; j < *marker + 1; j++)
862     if ((res = psiconv_list_add(*decoded,&value)))
863     goto ERROR2;
864     i += 4;
865     } else {
866     psiconv_debug(config,lev+2,off,"Marker: %02x value byte triplets follow",
867     0x100 - *marker);
868     for (j = 0; j < (0x100 - *marker); j++) {
869     psiconv_progress(config,lev+2,off,"Going to read value byte triplets at %04x",
870     i+j*3+1);
871     if (!(value0 = psiconv_list_get(encoded,i+j*3+1)))
872     goto ERROR2;
873     if (!(value1 = psiconv_list_get(encoded,i+j*3+2)))
874     goto ERROR2;
875     if (!(value2 = psiconv_list_get(encoded,i+j*3+3)))
876     goto ERROR2;
877     value = *value0 + (*value1 << 8) + (*value2 << 16);
878     psiconv_debug(config,lev+2,off,"Value: %06x",value);
879     if ((res = psiconv_list_add(*decoded,&value)))
880     goto ERROR2;
881     }
882     i += (0x100 - *marker)*3 + 1;
883     }
884     }
885     psiconv_progress(config,lev,off,
886     "End of RLE24 decoding process");
887     return 0;
888    
889     ERROR2:
890     psiconv_list_free(*decoded);
891     ERROR1:
892 frodo 184 psiconv_error(config,lev+1,off,"Decoding of RLE24 failed");
893 frodo 179 if (!res)
894     return -PSICONV_E_NOMEM;
895     else
896     return res;
897     }
898    
899 frodo 178 int psiconv_bytes_to_pixel_data(const psiconv_config config,
900     int lev, psiconv_u32 off,
901     const psiconv_pixel_bytes bytes,
902     psiconv_pixel_ints *pixels,
903     int colordepth, int xsize, int ysize)
904     {
905     int res=0;
906     int ibits,obits,x,y,bits;
907     psiconv_u8 input;
908     psiconv_u32 nr,output;
909     psiconv_u8 *ientry;
910    
911     psiconv_progress(config,lev+1,off,"Going to convert the bytes to pixels");
912     if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32))))
913     goto ERROR1;
914    
915     nr = 0;
916     for (y = 0; y < ysize; y++) {
917     /* New lines will start at longs */
918     while (nr % 4)
919     nr ++;
920     input = 0;
921     ibits = 0;
922     for (x= 0; x < xsize; x++) {
923 frodo 230 #ifdef LOUD
924 frodo 178 psiconv_progress(config,lev+2,off,
925     "Processing pixel at (x,y) = (%04x,%04x)",x,y);
926 frodo 230 #endif
927 frodo 178 output = 0;
928     obits = 0;
929     while (obits < colordepth) {
930     if (ibits == 0) {
931 frodo 230 #ifdef LOUD
932 frodo 178 psiconv_progress(config,lev+3,off,
933     "Going to read byte %08x",nr);
934 frodo 230 #endif
935 frodo 178 if (!(ientry = psiconv_list_get(bytes,nr)))
936     goto ERROR2;
937 frodo 230 #ifdef LOUD
938 frodo 178 psiconv_debug(config,lev+3,off,"Byte value: %02x",*ientry);
939 frodo 230 #endif
940 frodo 178 input = *ientry;
941     ibits = 8;
942     nr ++;
943     }
944     bits = ibits + obits > colordepth?colordepth-obits:ibits;
945     output = output << bits;
946     output |= input & ((1 << bits) - 1);
947     input = input >> bits;
948     ibits -= bits;
949     obits += bits;
950     }
951 frodo 230 #ifdef LOUD
952 frodo 178 psiconv_debug(config,lev+2,off,"Pixel value: %08x",output);
953 frodo 230 #endif
954 frodo 178 if ((res = psiconv_list_add(*pixels,&output)))
955     goto ERROR2;
956     }
957     }
958    
959     psiconv_progress(config,lev,off,
960     "Converting bytes to pixels completed");
961     return 0;
962    
963    
964     ERROR2:
965     psiconv_list_free(*pixels);
966     ERROR1:
967 frodo 184 psiconv_error(config,lev+1,off,"Converting bytes to pixels failed");
968 frodo 178 if (!res)
969     return -PSICONV_E_NOMEM;
970     else
971     return res;
972     }
973    
974     int psiconv_pixel_data_to_floats (const psiconv_config config, int lev,
975     psiconv_u32 off,
976     const psiconv_pixel_ints pixels,
977     psiconv_pixel_floats_t *floats,
978     int colordepth, int color,
979     int redbits, int bluebits, int greenbits,
980     const psiconv_pixel_floats_t palet)
981     {
982     int res = 0;
983     psiconv_u32 i;
984     psiconv_u32 *pixel;
985    
986     psiconv_progress(config,lev+1,off,"Going to convert pixels to floats");
987     if (!((*floats).red = malloc(psiconv_list_length(pixels) *
988     sizeof(*(*floats).red))))
989     goto ERROR1;
990     if (!((*floats).green = malloc(psiconv_list_length(pixels) *
991     sizeof(*(*floats).green))))
992     goto ERROR2;
993     if (!((*floats).blue = malloc(psiconv_list_length(pixels) *
994     sizeof(*(*floats).blue))))
995     goto ERROR3;
996     (*floats).length = psiconv_list_length(pixels);
997    
998     for (i = 0; i < psiconv_list_length(pixels); i++) {
999     if (!(pixel = psiconv_list_get(pixels,i)))
1000     goto ERROR4;
1001 frodo 230 #ifdef LOUD
1002 frodo 178 psiconv_progress(config,lev+2,off, "Handling pixel %04x (%04x)",i,*pixel);
1003 frodo 230 #endif
1004 frodo 178 if (!palet.length) {
1005     if (color) {
1006 frodo 179 (*floats).blue[i] = ((float) (*pixel & ((1 << bluebits) - 1))) /
1007 frodo 178 (1 << bluebits);
1008 frodo 179 (*floats).green[i] = ((float) ((*pixel >> bluebits) &
1009     ((1 << greenbits) - 1))) / (1 << greenbits);
1010     (*floats).red[i] = ((float) ((*pixel >> (bluebits+greenbits)) &
1011     ((1 << redbits) - 1))) / (1 << redbits);
1012 frodo 178 } else {
1013     (*floats).red[i] = (*floats).green[i] =
1014 frodo 179 (*floats).blue[i] = ((float) *pixel) /
1015     (1 << colordepth);
1016 frodo 178 }
1017     } else {
1018     if (*pixel >= palet.length) {
1019     psiconv_warn(config,lev+2,off,
1020     "Invalid palet color found (using color 0x00)");
1021     (*floats).red[i] = palet.red[0];
1022     (*floats).green[i] = palet.green[0];
1023     (*floats).blue[i] = palet.blue[0];
1024     } else {
1025     (*floats).red[i] = palet.red[*pixel];
1026     (*floats).green[i] = palet.green[*pixel];
1027     (*floats).blue[i] = palet.blue[*pixel];
1028     }
1029     }
1030 frodo 230 #ifdef LOUD
1031 frodo 178 psiconv_debug(config,lev+2,off, "Pixel: Red (%f), green (%f), blue (%f)",
1032     (*floats).red[i],(*floats).green[i],(*floats).blue[i]);
1033 frodo 230 #endif
1034 frodo 178 }
1035     psiconv_progress(config,lev+1,off,"Finished converting pixels to floats");
1036     return 0;
1037    
1038     ERROR4:
1039     free((*floats).blue);
1040     ERROR3:
1041     free((*floats).green);
1042     ERROR2:
1043     free((*floats).red);
1044     ERROR1:
1045 frodo 184 psiconv_error(config,lev+1,off,"Converting pixels to floats failed");
1046 frodo 178 if (!res)
1047     return -PSICONV_E_NOMEM;
1048     else
1049     return res;
1050     }
1051    
1052    
1053    

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