/[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 351 - (hide annotations)
Wed Oct 22 19:53:40 2014 UTC (9 years, 6 months ago) by frodo
File MIME type: text/plain
File size: 34520 byte(s)
(Frodo) Update copyright year in all source files

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

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