/[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 178 - (hide annotations)
Wed Dec 3 15:16:43 2003 UTC (20 years, 4 months ago) by frodo
File MIME type: text/plain
File size: 30062 byte(s)
(Frodo) Enhancing image parsing

* Preparations in parse_image to do a pass-based decoding with support for
  all image formats
* Moved some stuff to image.h/image.c that is used both for the generation
  and parsing of images
* image.h is not installed

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

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