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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 175 - (hide annotations)
Thu Nov 27 20:55:01 2003 UTC (20 years, 5 months ago) by frodo
File MIME type: text/plain
File size: 22700 byte(s)
(Frodo) RLE16/24 support, but not yet used

1 frodo 86 /*
2 frodo 174
3 frodo 86 generate_image.c - Part of psiconv, a PSION 5 file formats converter
4     Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl>
5    
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include "config.h"
22     #include "compat.h"
23    
24     #include "generate_routines.h"
25     #include "error.h"
26 frodo 175 #include "list.h"
27 frodo 86
28 frodo 142 #ifdef DMALLOC
29     #include <dmalloc.h>
30     #endif
31    
32 frodo 168 typedef psiconv_list psiconv_pixel_bytes; /* psiconv_u8 */
33 frodo 142
34 frodo 168 typedef psiconv_list psiconv_pixel_ints; /* of psiconv_u32 */
35    
36     typedef struct psiconv_pixel_float_s
37     {
38 frodo 170 psiconv_u32 length;
39 frodo 168 float *red;
40     float *green;
41     float *blue;
42     } psiconv_pixel_floats_t;
43    
44 frodo 170 static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,
45     int xsize,int ysize,
46 frodo 168 const psiconv_pixel_floats_t data,
47 frodo 170 int colordepth,
48 frodo 168 const psiconv_pixel_floats_t palet);
49 frodo 170 static int psiconv_pixel_data_to_bytes(const psiconv_config config,
50     psiconv_pixel_bytes *bytes, int xsize,
51 frodo 168 int ysize, const psiconv_pixel_ints pixels,
52     int colordepth);
53 frodo 175 static int psiconv_encode_rle8(const psiconv_config config,
54     const psiconv_pixel_bytes plain_bytes,
55     psiconv_pixel_bytes *encoded_bytes);
56     static int psiconv_encode_rle16(const psiconv_config config,
57     const psiconv_pixel_bytes plain_bytes,
58     psiconv_pixel_bytes *encoded_bytes);
59     static int psiconv_encode_rle24(const psiconv_config config,
60     const psiconv_pixel_bytes plain_bytes,
61     psiconv_pixel_bytes *encoded_bytes);
62 frodo 168
63 frodo 170 #define PALET_GREY_2_LEN 4
64     float palet_grey_2_rgb[PALET_GREY_2_LEN] = {0.0/3, 1.0/3, 2.0/3, 3.0/3};
65     #define PALET_GREY_4_LEN 16
66     float palet_grey_4_rgb[PALET_GREY_4_LEN] =
67     { 0.0/15, 1.0/15, 2.0/15, 3.0/15,
68 frodo 168 4.0/15, 5.0/15, 6.0/15, 7.0/15,
69     8.0/15, 9.0/15, 10.0/15, 11.0/15,
70     12.0/15, 13.0/15, 14.0/15, 15.0/15};
71 frodo 170 #define PALET_NONE_LEN 0
72 frodo 168
73     psiconv_pixel_floats_t palet_grey_2 =
74     {
75 frodo 170 PALET_GREY_2_LEN,
76 frodo 168 (float *) palet_grey_2_rgb,
77     (float *) palet_grey_2_rgb,
78     (float *) palet_grey_2_rgb
79     };
80    
81     psiconv_pixel_floats_t palet_grey_4 =
82     {
83 frodo 170 PALET_GREY_4_LEN,
84 frodo 168 (float *) palet_grey_4_rgb,
85     (float *) palet_grey_4_rgb,
86     (float *) palet_grey_4_rgb
87     };
88    
89 frodo 170 psiconv_pixel_floats_t palet_none =
90     {
91     PALET_NONE_LEN,
92     NULL,
93     NULL,
94     NULL
95     };
96 frodo 168
97 frodo 170
98 frodo 168 int psiconv_write_paint_data_section(const psiconv_config config,
99 frodo 170 psiconv_buffer buf,
100 frodo 174 const psiconv_paint_data_section value,
101     int is_clipart)
102 frodo 168 {
103 frodo 170 int res,colordepth,i;
104     psiconv_pixel_ints ints;
105     psiconv_pixel_floats_t floats,palet;
106 frodo 175 psiconv_list bytes,bytes_rle;
107     psiconv_u8 *byteptr,encoding;
108 frodo 168
109     if (!value) {
110     psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section");
111     res = -PSICONV_E_GENERATE;
112     goto ERROR1;
113     }
114    
115 frodo 170 floats.red = value->red;
116     floats.green = value->green;
117     floats.blue = value->blue;
118     floats.length = value->xsize * value->ysize;
119    
120     switch (config->colordepth) {
121     default:
122     case 2: palet = (config->color?palet_none:palet_grey_2);
123     break;
124     case 4: palet = (config->color?palet_none:palet_grey_4);
125     break;
126     }
127    
128     if ((res = psiconv_collect_pixel_data(&ints,value->xsize,
129     value->ysize,floats,
130     config->colordepth,palet)))
131 frodo 168 goto ERROR1;
132 frodo 170
133     if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize,
134     ints,config->colordepth)))
135     goto ERROR2;
136    
137 frodo 175
138     encoding = 0x00;
139     if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle)))
140 frodo 170 goto ERROR3;
141 frodo 175 if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) {
142     encoding = 0x01;
143     psiconv_list_free(bytes);
144     bytes = bytes_rle;
145     } else {
146     bytes_rle = NULL;
147     }
148    
149     if ((res = psiconv_write_u32(config,buf,
150     0x28+psiconv_list_length(bytes))))
151     goto ERROR3;
152 frodo 170 if ((res = psiconv_write_u32(config,buf,0x28)))
153     goto ERROR3;
154     if ((res = psiconv_write_u32(config,buf,value->xsize)))
155     goto ERROR3;
156     if ((res = psiconv_write_u32(config,buf,value->ysize)))
157     goto ERROR3;
158     if ((res = psiconv_write_length(config,buf,value->pic_xsize)))
159     goto ERROR3;
160     if ((res = psiconv_write_length(config,buf,value->pic_ysize)))
161     goto ERROR3;
162     colordepth = config->colordepth;
163     if ((colordepth != 2) && colordepth != 4)
164     colordepth = 2;
165     if ((res = psiconv_write_u32(config,buf,colordepth)))
166     goto ERROR3;
167     if ((res = psiconv_write_u32(config,buf,(config->color?1:0))))
168     goto ERROR3;
169     if ((res = psiconv_write_u32(config,buf,0)))
170     goto ERROR3;
171 frodo 175 if ((res = psiconv_write_u32(config,buf,encoding)))
172 frodo 170 goto ERROR3;
173 frodo 174 if (is_clipart) {
174     if ((res = psiconv_write_u32(config,buf,0xffffffff)))
175     goto ERROR3;
176     if ((res = psiconv_write_u32(config,buf,0x00000044)))
177     goto ERROR3;
178     }
179 frodo 170 for (i = 0; i < psiconv_list_length(bytes); i++) {
180     if (!(byteptr = psiconv_list_get(bytes,i)))
181     goto ERROR3;
182     if ((res = psiconv_write_u8(config,buf,*byteptr)))
183     goto ERROR3;
184 frodo 168 }
185    
186 frodo 170 ERROR3:
187     psiconv_list_free(bytes);
188 frodo 168 ERROR2:
189 frodo 170 psiconv_list_free(ints);
190 frodo 168 ERROR1:
191     return res;
192     }
193    
194     /* Translate the floating point RGB information into pixel values.
195     The palet is optional; without it, we just use the
196     colordepth. With a large palet this is not very fast, but it will do for
197     now. For greyscale pictures, just use the palet. */
198 frodo 170 int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize,
199 frodo 168 const psiconv_pixel_floats_t data,
200 frodo 170 int colordepth,
201 frodo 168 const psiconv_pixel_floats_t palet)
202     {
203     int res,x,y,i;
204 frodo 170 psiconv_u32 index,pixel;
205 frodo 168 float p_red,p_green,p_blue,mult,dist,new_dist;
206    
207     if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) {
208     res = -PSICONV_E_NOMEM;
209     goto ERROR1;
210     }
211    
212     mult = 1 << colordepth;
213     for (y = 0; y < ysize; y++) {
214     for (x = 0; x < xsize; x++) {
215 frodo 170 index = y*xsize+x;
216 frodo 168 p_red = data.red[index];
217     p_green = data.green[index];
218     p_blue = data.blue[index];
219 frodo 170 if (!palet.length) {
220     pixel = (((psiconv_u32) (p_red*mult+0.5)) << (2*colordepth)) +
221     (((psiconv_u32) (p_green*mult+0.5)) << colordepth) +
222     ((psiconv_u32) (p_blue*mult+0.5));
223 frodo 168 } else {
224     dist = 4; /* Max distance is 3, so this is safe */
225     pixel = -1;
226 frodo 170 for (i = 0; i < palet.length; i++) {
227 frodo 168 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) +
228     (p_green - palet.green[i]) * (p_green - palet.green[i]) +
229     (p_blue - palet.blue[i]) * (p_blue - palet.blue[i]);
230     if (new_dist < dist) {
231     pixel = i;
232     dist = new_dist;
233     }
234     }
235     }
236     if ((res = psiconv_list_add(*pixels,&pixel)))
237     goto ERROR2;
238     }
239     }
240     return 0;
241    
242     ERROR2:
243     psiconv_list_free(*pixels);
244     ERROR1:
245     return res;
246     }
247    
248 frodo 170 int psiconv_pixel_data_to_bytes(const psiconv_config config,
249     psiconv_pixel_bytes *bytes, int xsize,
250 frodo 168 int ysize, const psiconv_pixel_ints pixels,
251     int colordepth)
252     {
253     int res;
254     int x,y;
255    
256     psiconv_u32 inputdata;
257     psiconv_u8 outputbyte;
258     psiconv_u32 *pixelptr;
259 frodo 170 int inputbitsleft,outputbitnr,bitsfit,outputbytenr;
260 frodo 168
261    
262     if (!bytes) {
263     psiconv_warn(config,0,0,"NULL pixel data");
264     res = -PSICONV_E_GENERATE;
265     goto ERROR1;
266     }
267     if (!pixels) {
268     psiconv_warn(config,0,0,"NULL pixel data");
269     res = -PSICONV_E_GENERATE;
270     goto ERROR1;
271     }
272     if (psiconv_list_length(pixels) != xsize * ysize) {
273     psiconv_warn(config,0,0,"Pixel number is not correct");
274     res = -PSICONV_E_GENERATE;
275     goto ERROR1;
276     }
277    
278     if (!(*bytes = psiconv_list_new(sizeof(psiconv_u8)))) {
279     res = -PSICONV_E_NOMEM;
280     goto ERROR1;
281     }
282    
283    
284     outputbitnr = 0;
285     outputbyte = 0;
286     for (y = 0; y < ysize; y++) {
287 frodo 170 outputbytenr = 0;
288 frodo 168 for (x = 0; x < xsize; x++) {
289     if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) {
290     psiconv_warn(config,0,0,"Massive internal corruption");
291     res = -PSICONV_E_NOMEM;
292     goto ERROR2;
293     }
294     inputbitsleft = colordepth;
295     inputdata = *pixelptr;
296     while (inputbitsleft) {
297     bitsfit = (inputbitsleft+outputbitnr<=8?inputbitsleft:8-outputbitnr);
298     outputbyte |= (inputdata & ((1 << bitsfit) - 1)) << outputbitnr;
299     inputdata = inputdata >> bitsfit;
300     inputbitsleft -= bitsfit;
301     outputbitnr += bitsfit;
302     if (outputbitnr == 8) {
303     if ((res = psiconv_list_add(*bytes,&outputbyte)))
304     goto ERROR2;
305     outputbitnr = 0;
306     outputbyte = 0;
307 frodo 170 outputbytenr ++;
308 frodo 168 }
309     }
310     }
311 frodo 170 /* Always end lines on a long border */
312 frodo 168 if (outputbitnr != 0) {
313     if ((res = psiconv_list_add(*bytes,&outputbyte)))
314     goto ERROR2;
315     outputbitnr = 0;
316     outputbyte = 0;
317 frodo 170 outputbytenr ++;
318 frodo 168 }
319 frodo 170
320     while (outputbytenr % 0x04) {
321     if ((res = psiconv_list_add(*bytes,&outputbyte)))
322     goto ERROR2;
323     outputbytenr ++;
324     }
325 frodo 168 }
326    
327     return 0;
328    
329     ERROR2:
330     psiconv_list_free(*bytes);
331     ERROR1:
332     return res;
333     }
334 frodo 170
335 frodo 175 int psiconv_encode_rle8(const psiconv_config config,
336     const psiconv_pixel_bytes plain_bytes,
337     psiconv_pixel_bytes *encoded_bytes)
338     {
339     int res,i,j,len;
340     psiconv_u8 *entry,*next;
341     psiconv_u8 temp;
342    
343     if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry)))) {
344     res = -PSICONV_E_NOMEM;
345     goto ERROR1;
346     }
347    
348     for (i = 0; i < psiconv_list_length(plain_bytes);) {
349     if (!(entry = psiconv_list_get(plain_bytes,i))) {
350     res = -PSICONV_E_NOMEM;
351     goto ERROR2;
352     }
353     if (!(next = psiconv_list_get(plain_bytes,i+1))) {
354     res = -PSICONV_E_NOMEM;
355     goto ERROR2;
356     }
357     if (i == psiconv_list_length(plain_bytes) - 2) {
358     temp = 0xfe;
359     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
360     goto ERROR2;
361     if ((res = psiconv_list_add(*encoded_bytes,entry)))
362     goto ERROR2;
363     if ((res = psiconv_list_add(*encoded_bytes,next)))
364     goto ERROR2;
365     i +=2;
366     } else if (*next == *entry) {
367     len = 0;
368     while ((*next == *entry) &&
369     (i+len + 1 < psiconv_list_length(plain_bytes)) &&
370     len < 0x80) {
371     len ++;
372     if (!(next = psiconv_list_get(plain_bytes,i+len))) {
373     res = -PSICONV_E_NOMEM;
374     goto ERROR2;
375     }
376     }
377     temp = len - 1;
378     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
379     goto ERROR2;
380     if ((res = psiconv_list_add(*encoded_bytes,entry)))
381     goto ERROR2;
382     i += len;
383     } else {
384     len = 1;
385     while ((*next != *entry) &&
386     (i+len+1 < psiconv_list_length(plain_bytes)) &&
387     len < 0x80) {
388     len ++;
389     entry = next;
390     if (!(next = psiconv_list_get(plain_bytes,i+len))) {
391     res = -PSICONV_E_NOMEM;
392     goto ERROR2;
393     }
394     }
395     len --;
396     temp = 0x100 - len;
397     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
398     goto ERROR2;
399     for (j = 0; j < len; j++) {
400     if (!(next = psiconv_list_get(plain_bytes,i+j))) {
401     res = -PSICONV_E_NOMEM;
402     goto ERROR2;
403     }
404     if ((res = psiconv_list_add(*encoded_bytes,next)))
405     goto ERROR2;
406     }
407     i += len;
408     }
409     }
410     return 0;
411    
412     ERROR2:
413     psiconv_list_free(*encoded_bytes);
414     ERROR1:
415     return res;
416     }
417    
418     int psiconv_encode_rle16(const psiconv_config config,
419     const psiconv_pixel_bytes plain_bytes,
420     psiconv_pixel_bytes *encoded_bytes)
421     {
422     int res,i,j,len;
423     psiconv_u8 *entry1,*entry2,*next1,*next2;
424     psiconv_u8 temp;
425    
426     if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) {
427     res = -PSICONV_E_NOMEM;
428     goto ERROR1;
429     }
430    
431     for (i = 0; i < psiconv_list_length(plain_bytes);) {
432     if (!(entry1 = psiconv_list_get(plain_bytes,i))) {
433     res = -PSICONV_E_NOMEM;
434     goto ERROR2;
435     }
436     if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) {
437     res = -PSICONV_E_NOMEM;
438     goto ERROR2;
439     }
440     if (!(next1 = psiconv_list_get(plain_bytes,i+2))) {
441     res = -PSICONV_E_NOMEM;
442     goto ERROR2;
443     }
444     if (!(next2 = psiconv_list_get(plain_bytes,i+3))) {
445     res = -PSICONV_E_NOMEM;
446     goto ERROR2;
447     }
448     if (i == psiconv_list_length(plain_bytes) - 4) {
449     temp = 0xfe;
450     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
451     goto ERROR2;
452     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
453     goto ERROR2;
454     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
455     goto ERROR2;
456     if ((res = psiconv_list_add(*encoded_bytes,next1)))
457     goto ERROR2;
458     if ((res = psiconv_list_add(*encoded_bytes,next2)))
459     goto ERROR2;
460     i +=4;
461     } else if ((*next1 == *entry1) && (*next2 == *entry2)) {
462     len = 0;
463     while (((*next1 == *entry1) && (*next2 == *entry2)) &&
464     (i+2*len + 4 < psiconv_list_length(plain_bytes)) &&
465     len < 0x80) {
466     len ++;
467     if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) {
468     res = -PSICONV_E_NOMEM;
469     goto ERROR2;
470     }
471     if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) {
472     res = -PSICONV_E_NOMEM;
473     goto ERROR2;
474     }
475     }
476     temp = len - 1;
477     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
478     goto ERROR2;
479     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
480     goto ERROR2;
481     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
482     goto ERROR2;
483     i += len*2;
484     } else {
485     len = 1;
486     while (((*next1 != *entry1) || (*next2 != *entry2))&&
487     (i+len*2+4 < psiconv_list_length(plain_bytes)) &&
488     len < 0x80) {
489     len ++;
490     entry1 = next1;
491     entry2 = next2;
492     if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) {
493     res = -PSICONV_E_NOMEM;
494     goto ERROR2;
495     }
496     if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) {
497     res = -PSICONV_E_NOMEM;
498     goto ERROR2;
499     }
500     }
501     len --;
502     temp = 0x100 - len;
503     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
504     goto ERROR2;
505     for (j = 0; j < len; j++) {
506     if (!(next1 = psiconv_list_get(plain_bytes,i+j*2))) {
507     res = -PSICONV_E_NOMEM;
508     goto ERROR2;
509     }
510     if (!(next2 = psiconv_list_get(plain_bytes,i+j*2+1))) {
511     res = -PSICONV_E_NOMEM;
512     goto ERROR2;
513     }
514     if ((res = psiconv_list_add(*encoded_bytes,next1)))
515     goto ERROR2;
516     if ((res = psiconv_list_add(*encoded_bytes,next2)))
517     goto ERROR2;
518     }
519     i += len*2;
520     }
521     }
522     return 0;
523    
524     ERROR2:
525     psiconv_list_free(*encoded_bytes);
526     ERROR1:
527     return res;
528     }
529    
530     int psiconv_encode_rle24(const psiconv_config config,
531     const psiconv_pixel_bytes plain_bytes,
532     psiconv_pixel_bytes *encoded_bytes)
533     {
534     int res,i,j,len;
535     psiconv_u8 *entry1,*entry2,*entry3,*next1,*next2,*next3;
536     psiconv_u8 temp;
537    
538     if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) {
539     res = -PSICONV_E_NOMEM;
540     goto ERROR1;
541     }
542    
543     for (i = 0; i < psiconv_list_length(plain_bytes);) {
544     if (!(entry1 = psiconv_list_get(plain_bytes,i))) {
545     res = -PSICONV_E_NOMEM;
546     goto ERROR2;
547     }
548     if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) {
549     res = -PSICONV_E_NOMEM;
550     goto ERROR2;
551     }
552     if (!(entry3 = psiconv_list_get(plain_bytes,i+2))) {
553     res = -PSICONV_E_NOMEM;
554     goto ERROR2;
555     }
556     if (!(next1 = psiconv_list_get(plain_bytes,i+3))) {
557     res = -PSICONV_E_NOMEM;
558     goto ERROR2;
559     }
560     if (!(next2 = psiconv_list_get(plain_bytes,i+4))) {
561     res = -PSICONV_E_NOMEM;
562     goto ERROR2;
563     }
564     if (!(next3 = psiconv_list_get(plain_bytes,i+5))) {
565     res = -PSICONV_E_NOMEM;
566     goto ERROR2;
567     }
568     if (i == psiconv_list_length(plain_bytes) - 6) {
569     temp = 0xfe;
570     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
571     goto ERROR2;
572     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
573     goto ERROR2;
574     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
575     goto ERROR2;
576     if ((res = psiconv_list_add(*encoded_bytes,entry3)))
577     goto ERROR2;
578     if ((res = psiconv_list_add(*encoded_bytes,next1)))
579     goto ERROR2;
580     if ((res = psiconv_list_add(*encoded_bytes,next2)))
581     goto ERROR2;
582     if ((res = psiconv_list_add(*encoded_bytes,next3)))
583     goto ERROR2;
584     i +=4;
585     } else if ((*next1 == *entry1) && (*next2 == *entry2) &&
586     (*next3 == *entry3)) {
587     len = 0;
588     while (((*next1 == *entry1) && (*next2 == *entry2) &&
589     (*next3 == *entry3)) &&
590     (i+3*len + 6 < psiconv_list_length(plain_bytes)) &&
591     len < 0x80) {
592     len ++;
593     if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) {
594     res = -PSICONV_E_NOMEM;
595     goto ERROR2;
596     }
597     if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) {
598     res = -PSICONV_E_NOMEM;
599     goto ERROR2;
600     }
601     if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) {
602     res = -PSICONV_E_NOMEM;
603     goto ERROR2;
604     }
605     }
606     temp = len - 1;
607     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
608     goto ERROR2;
609     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
610     goto ERROR2;
611     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
612     goto ERROR2;
613     if ((res = psiconv_list_add(*encoded_bytes,entry3)))
614     goto ERROR2;
615     i += len*3;
616     } else {
617     len = 1;
618     while (((*next1 != *entry1) || (*next2 != *entry2) ||
619     (*next3 != *entry3)) &&
620     (i+len*3+6 < psiconv_list_length(plain_bytes)) &&
621     len < 0x80) {
622     len ++;
623     entry1 = next1;
624     entry2 = next2;
625     entry3 = next3;
626     if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) {
627     res = -PSICONV_E_NOMEM;
628     goto ERROR2;
629     }
630     if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) {
631     res = -PSICONV_E_NOMEM;
632     goto ERROR2;
633     }
634     if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) {
635     res = -PSICONV_E_NOMEM;
636     goto ERROR2;
637     }
638     }
639     len --;
640     temp = 0x100 - len;
641     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
642     goto ERROR2;
643     for (j = 0; j < len; j++) {
644     if (!(next1 = psiconv_list_get(plain_bytes,i+j*3))) {
645     res = -PSICONV_E_NOMEM;
646     goto ERROR2;
647     }
648     if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+1))) {
649     res = -PSICONV_E_NOMEM;
650     goto ERROR2;
651     }
652     if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+2))) {
653     res = -PSICONV_E_NOMEM;
654     goto ERROR2;
655     }
656     if ((res = psiconv_list_add(*encoded_bytes,next1)))
657     goto ERROR2;
658     if ((res = psiconv_list_add(*encoded_bytes,next2)))
659     goto ERROR2;
660     if ((res = psiconv_list_add(*encoded_bytes,next3)))
661     goto ERROR2;
662     }
663     i += len*3;
664     }
665     }
666     return 0;
667    
668     ERROR2:
669     psiconv_list_free(*encoded_bytes);
670     ERROR1:
671     return res;
672     }
673    
674    
675 frodo 170 int psiconv_write_sketch_section(const psiconv_config config,
676     psiconv_buffer buf,
677 frodo 171 const psiconv_sketch_section value)
678 frodo 170 {
679     int res;
680    
681     if (!value) {
682     psiconv_warn(config,0,0,"NULL sketch section");
683     res = -PSICONV_E_GENERATE;
684     goto ERROR1;
685     }
686    
687     if ((res = psiconv_write_u16(config,buf,value->displayed_xsize)))
688     goto ERROR1;
689     if ((res = psiconv_write_u16(config,buf,value->displayed_ysize)))
690     goto ERROR1;
691     if ((res = psiconv_write_u16(config,buf,value->picture_data_x_offset)))
692     goto ERROR1;
693     if ((res = psiconv_write_u16(config,buf,value->picture_data_y_offset)))
694     goto ERROR1;
695     if ((res = psiconv_write_u16(config,buf,value->displayed_size_x_offset)))
696     goto ERROR1;
697     if ((res = psiconv_write_u16(config,buf,value->displayed_size_y_offset)))
698     goto ERROR1;
699     if ((res = psiconv_write_u16(config,buf,value->form_xsize)))
700     goto ERROR1;
701     if ((res = psiconv_write_u16(config,buf,value->form_ysize)))
702     goto ERROR1;
703     if ((res = psiconv_write_u16(config,buf,0x0000)))
704     goto ERROR1;
705 frodo 174 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,0)))
706 frodo 170 goto ERROR1;
707     if ((res = psiconv_write_u16(config,buf,value->magnification_x * 0x03e8)))
708     goto ERROR1;
709     if ((res = psiconv_write_u16(config,buf,value->magnification_y * 0x03e8)))
710     goto ERROR1;
711     if ((res = psiconv_write_u32(config,buf,value->cut_left * 0x0c *
712     value->displayed_xsize)))
713     goto ERROR1;
714     if ((res = psiconv_write_u32(config,buf,value->cut_right * 0x0c *
715     value->displayed_xsize)))
716     goto ERROR1;
717     if ((res = psiconv_write_u32(config,buf,value->cut_top * 0x0c *
718     value->displayed_ysize)))
719     goto ERROR1;
720     if ((res = psiconv_write_u32(config,buf,value->cut_bottom * 0x0c *
721     value->displayed_ysize)))
722     goto ERROR1;
723    
724     ERROR1:
725     return res;
726     }
727 frodo 171
728 frodo 175 int psiconv_write_clipart_section(const psiconv_config config,
729     psiconv_buffer buf,
730     const psiconv_clipart_section value)
731     {
732     int res;
733    
734    
735     if (!value) {
736     psiconv_warn(config,0,psiconv_buffer_length(buf),
737     "NULL Clipart Section");
738     res = -PSICONV_E_GENERATE;
739     goto ERROR;
740     }
741     if ((res = psiconv_write_u32(config,buf,PSICONV_ID_CLIPART_ITEM)))
742     goto ERROR;
743     if ((res = psiconv_write_u32(config,buf,0x00000002)))
744     goto ERROR;
745     if ((res = psiconv_write_u32(config,buf,0x00000000)))
746     goto ERROR;
747     if ((res = psiconv_write_u32(config,buf,0x00000000)))
748     goto ERROR;
749     if ((res = psiconv_write_u32(config,buf,0x0000000C)))
750     goto ERROR;
751     if ((res = psiconv_write_paint_data_section(config,buf,value->picture,1)))
752     goto ERROR;
753    
754     ERROR:
755     return res;
756     }
757    
758 frodo 171 int psiconv_write_jumptable_section(const psiconv_config config,
759     psiconv_buffer buf,
760     const psiconv_jumptable_section value)
761     {
762     int res,i;
763     psiconv_u32 *offset_ptr;
764    
765    
766     if (!value) {
767     psiconv_warn(config,0,psiconv_buffer_length(buf),
768     "NULL Jumptable Section");
769     res = -PSICONV_E_GENERATE;
770     goto ERROR;
771     }
772     if ((res = psiconv_write_u32(config,buf,psiconv_list_length(value))))
773     goto ERROR;
774     for (i = 0; i < psiconv_list_length(value); i++) {
775     if (!(offset_ptr = psiconv_list_get(value,i))) {
776     psiconv_warn(config,0,psiconv_buffer_length(buf),
777     "Massive memory corruption");
778     res = -PSICONV_E_NOMEM;
779     goto ERROR;
780     }
781     if ((res = psiconv_write_offset(config,buf,*offset_ptr)))
782     goto ERROR;
783     }
784    
785     ERROR:
786     return res;
787     }
788 frodo 174

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