/[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 179 - (hide annotations)
Sat Dec 13 18:23:16 2003 UTC (20 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 34218 byte(s)
(Frodo) Revamped and expanded image (paint data section) parsing

Color images are now supported
Colordepths besides 2 bit are now supported
RLE12,16 and 24 are now supported
All of the above are experimental

Parsing of images takes some more memory, but the code structure is much
simpler.

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

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