/[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 176 - (hide annotations)
Tue Dec 2 19:47:47 2003 UTC (20 years, 4 months ago) by frodo
File MIME type: text/plain
File size: 45139 byte(s)
(Frodo) Picture generation now supports all RLE's and many more config
        items. Mostly untested, though.

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 176 int colordepth,int color,
48     int redbits,int greenbits,int bluebits,
49 frodo 168 const psiconv_pixel_floats_t palet);
50 frodo 170 static int psiconv_pixel_data_to_bytes(const psiconv_config config,
51     psiconv_pixel_bytes *bytes, int xsize,
52 frodo 168 int ysize, const psiconv_pixel_ints pixels,
53     int colordepth);
54 frodo 175 static int psiconv_encode_rle8(const psiconv_config config,
55     const psiconv_pixel_bytes plain_bytes,
56     psiconv_pixel_bytes *encoded_bytes);
57 frodo 176 static int psiconv_encode_rle12(const psiconv_config config,
58     const psiconv_pixel_bytes plain_bytes,
59     psiconv_pixel_bytes *encoded_bytes);
60 frodo 175 static int psiconv_encode_rle16(const psiconv_config config,
61     const psiconv_pixel_bytes plain_bytes,
62     psiconv_pixel_bytes *encoded_bytes);
63     static int psiconv_encode_rle24(const psiconv_config config,
64     const psiconv_pixel_bytes plain_bytes,
65     psiconv_pixel_bytes *encoded_bytes);
66 frodo 168
67 frodo 170 #define PALET_NONE_LEN 0
68 frodo 168
69 frodo 176 psiconv_pixel_floats_t palet_none =
70 frodo 168 {
71 frodo 176 PALET_NONE_LEN,
72     NULL,
73     NULL,
74     NULL
75 frodo 168 };
76    
77 frodo 176 #define PALET_COLOR_4_LEN 16
78     float palet_color_4_red[PALET_COLOR_4_LEN] =
79     { 0x00/256.0, 0x55/256.0, 0x80/256.0, 0x80/256.0, /* 0x00 */
80     0x00/256.0, 0xff/256.0, 0x00/256.0, 0xff/256.0, /* 0x04 */
81     0xff/256.0, 0x00/256.0, 0x00/256.0, 0x80/256.0, /* 0x08 */
82     0x00/256.0, 0x00/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */
83     };
84    
85     float palet_color_4_green[PALET_COLOR_4_LEN] =
86     { 0x00/256.0, 0x55/256.0, 0x00/256.0, 0x80/256.0, /* 0x00 */
87     0x80/256.0, 0x00/256.0, 0xff/256.0, 0xff/256.0, /* 0x04 */
88     0x00/256.0, 0xff/256.0, 0xff/256.0, 0x00/256.0, /* 0x08 */
89     0x00/256.0, 0x80/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */
90     };
91    
92     float palet_color_4_blue[PALET_COLOR_4_LEN] =
93     { 0x00/256.0, 0x55/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */
94     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x04 */
95     0xff/256.0, 0x00/256.0, 0xff/256.0, 0x80/256.0, /* 0x08 */
96     0x80/256.0, 0x80/256.0, 0xaa/256.0, 0xff/256.0 /* 0x0c */
97     };
98    
99     psiconv_pixel_floats_t palet_color_4 =
100 frodo 168 {
101 frodo 176 PALET_COLOR_4_LEN,
102     palet_color_4_red,
103     palet_color_4_green,
104     palet_color_4_blue,
105 frodo 168 };
106    
107 frodo 176 #define PALET_COLOR_8_LEN 256
108     float palet_color_8_red[PALET_COLOR_8_LEN] =
109     { 0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x00 */
110     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x04 */
111     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x08 */
112     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x0c */
113     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x10 */
114     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x14 */
115     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x18 */
116     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x1c */
117     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x20 */
118     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x24 */
119     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x28 */
120     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x2c */
121     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x30 */
122     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x34 */
123     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x38 */
124     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x3c */
125     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x40 */
126     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x44 */
127     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x48 */
128     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x4c */
129     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x50 */
130     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x54 */
131     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x58 */
132     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x5c */
133     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x60 */
134     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x64 */
135     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x68 */
136     0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */
137     0x77/256.0, 0x11/256.0, 0x22/256.0, 0x44/256.0, /* 0x70 */
138     0x55/256.0, 0x77/256.0, 0x00/256.0, 0x00/256.0, /* 0x74 */
139     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x78 */
140     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x7c */
141     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x80 */
142     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x84 */
143     0x00/256.0, 0x00/256.0, 0x88/256.0, 0xaa/256.0, /* 0x88 */
144     0xbb/256.0, 0xdd/256.0, 0xee/256.0, 0x88/256.0, /* 0x8c */
145     0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */
146     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0x94 */
147     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0x98 */
148     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0x9c */
149     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xa0 */
150     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xa4 */
151     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xa8 */
152     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xac */
153     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xb0 */
154     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xb4 */
155     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xb8 */
156     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xbc */
157     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xc0 */
158     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xc4 */
159     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xc8 */
160     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xcc */
161     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xd0 */
162     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xd4 */
163     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xd8 */
164     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xdc */
165     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xe0 */
166     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xe4 */
167     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xe8 */
168     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xec */
169     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0, /* 0xf0 */
170     0x00/256.0, 0x33/256.0, 0x66/256.0, 0x99/256.0, /* 0xf4 */
171     0xcc/256.0, 0xff/256.0, 0x00/256.0, 0x33/256.0, /* 0xf8 */
172     0x66/256.0, 0x99/256.0, 0xcc/256.0, 0xff/256.0 /* 0xfc */
173     };
174    
175     float palet_color_8_green[PALET_COLOR_8_LEN] =
176     { 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */
177     0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x04 */
178     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x08 */
179     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x0c */
180     0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x10 */
181     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x14 */
182     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x18 */
183     0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x1c */
184     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x20 */
185     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x24 */
186     0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x28 */
187     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x2c */
188     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x30 */
189     0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x34 */
190     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x38 */
191     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x3c */
192     0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x40 */
193     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x44 */
194     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x48 */
195     0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x4c */
196     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x50 */
197     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x54 */
198     0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0x58 */
199     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x5c */
200     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0x60 */
201     0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0x64 */
202     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0x68 */
203     0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */
204     0x77/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x70 */
205     0x00/256.0, 0x00/256.0, 0x11/256.0, 0x22/256.0, /* 0x74 */
206     0x44/256.0, 0x55/256.0, 0x77/256.0, 0x00/256.0, /* 0x78 */
207     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x7c */
208     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x80 */
209     0x00/256.0, 0x88/256.0, 0xaa/256.0, 0xbb/256.0, /* 0x84 */
210     0xdd/256.0, 0xee/256.0, 0x00/256.0, 0x00/256.0, /* 0x88 */
211     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x88/256.0, /* 0x8c */
212     0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */
213     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x94 */
214     0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0x98 */
215     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x9c */
216     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xa0 */
217     0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xa4 */
218     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa8 */
219     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xac */
220     0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xb0 */
221     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xb4 */
222     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0xb8 */
223     0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0xbc */
224     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0xc0 */
225     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xc4 */
226     0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xc8 */
227     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xcc */
228     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd0 */
229     0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xd4 */
230     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xd8 */
231     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0xdc */
232     0x00/256.0, 0x00/256.0, 0x33/256.0, 0x33/256.0, /* 0xe0 */
233     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0xe4 */
234     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0xe8 */
235     0x66/256.0, 0x66/256.0, 0x99/256.0, 0x99/256.0, /* 0xec */
236     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xf0 */
237     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xf4 */
238     0xcc/256.0, 0xcc/256.0, 0xff/256.0, 0xff/256.0, /* 0xf8 */
239     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xfc */
240     };
241    
242     float palet_color_8_blue[PALET_COLOR_8_LEN] =
243     { 0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x00 */
244     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x04 */
245     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x08 */
246     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x0c */
247     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x10 */
248     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x14 */
249     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x18 */
250     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x1c */
251     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x20 */
252     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x24 */
253     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x28 */
254     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x2c */
255     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x30 */
256     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x34 */
257     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x38 */
258     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x3c */
259     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x40 */
260     0x33/256.0, 0x33/256.0, 0x33/256.0, 0x33/256.0, /* 0x44 */
261     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x48 */
262     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x4c */
263     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x50 */
264     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x54 */
265     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x58 */
266     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x5c */
267     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x60 */
268     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x64 */
269     0x66/256.0, 0x66/256.0, 0x66/256.0, 0x66/256.0, /* 0x68 */
270     0x11/256.0, 0x22/256.0, 0x44/256.0, 0x55/256.0, /* 0x6c */
271     0x77/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x70 */
272     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x74 */
273     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x11/256.0, /* 0x78 */
274     0x22/256.0, 0x44/256.0, 0x55/256.0, 0x77/256.0, /* 0x7c */
275     0x88/256.0, 0xaa/256.0, 0xbb/256.0, 0xdd/256.0, /* 0x80 */
276     0xee/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x84 */
277     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x00/256.0, /* 0x88 */
278     0x00/256.0, 0x00/256.0, 0x00/256.0, 0x88/256.0, /* 0x8c */
279     0xaa/256.0, 0xbb/256.0, 0xdd/256.0, 0xee/256.0, /* 0x90 */
280     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x94 */
281     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x98 */
282     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0x9c */
283     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa0 */
284     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa4 */
285     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xa8 */
286     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xac */
287     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xb0 */
288     0x99/256.0, 0x99/256.0, 0x99/256.0, 0x99/256.0, /* 0xb4 */
289     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xb8 */
290     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xbc */
291     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc0 */
292     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc4 */
293     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xc8 */
294     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xcc */
295     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd0 */
296     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd4 */
297     0xcc/256.0, 0xcc/256.0, 0xcc/256.0, 0xcc/256.0, /* 0xd8 */
298     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xdc */
299     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe0 */
300     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe4 */
301     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xe8 */
302     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xec */
303     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf0 */
304     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf4 */
305     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xf8 */
306     0xff/256.0, 0xff/256.0, 0xff/256.0, 0xff/256.0, /* 0xfc */
307     };
308    
309     psiconv_pixel_floats_t palet_color_8 =
310 frodo 170 {
311 frodo 176 PALET_COLOR_8_LEN,
312     palet_color_8_red,
313     palet_color_8_green,
314     palet_color_8_blue,
315 frodo 170 };
316 frodo 168
317     int psiconv_write_paint_data_section(const psiconv_config config,
318 frodo 170 psiconv_buffer buf,
319 frodo 174 const psiconv_paint_data_section value,
320     int is_clipart)
321 frodo 168 {
322 frodo 170 int res,colordepth,i;
323     psiconv_pixel_ints ints;
324     psiconv_pixel_floats_t floats,palet;
325 frodo 175 psiconv_list bytes,bytes_rle;
326     psiconv_u8 *byteptr,encoding;
327 frodo 168
328 frodo 176 /* First, we check whether we can cope with the current configuration.
329     If not, we stop at once */
330     if ((config->colordepth != 2) && (config->colordepth != 4) &&
331     (config->colordepth != 8) && (config->colordepth != 12) &&
332     (config->colordepth != 16) && (config->colordepth != 24)) {
333     psiconv_warn(config,0,psiconv_buffer_length(buf),
334     "Unsupported color depth (%d); try 2, 4, 8, 16 or 24",
335     config->colordepth);
336     res = -PSICONV_E_GENERATE;
337     goto ERROR1;
338     }
339    
340     if ((config->color) &&
341     (config->bluebits || config->redbits || config->greenbits) &&
342     (config->bluebits+config->redbits+config->greenbits!=config->colordepth)) {
343     psiconv_warn(config,0,psiconv_buffer_length(buf),
344     "Sum of red (%d), green (%d) and blue (%d) bits should be "
345     "equal to the color depth (%d)",
346     config->redbits,config->greenbits,config->bluebits,
347     config->colordepth);
348     res = -PSICONV_E_GENERATE;
349     goto ERROR1;
350     }
351    
352     if (config->color &&
353     !(config->redbits || config->greenbits || config->bluebits) &&
354     (config->colordepth != 4) && (config->colordepth != 8)) {
355     psiconv_warn(config,0,psiconv_buffer_length(buf),
356     "Current color depth (%d) has no palet associated with it",
357     config->colordepth);
358     res = -PSICONV_E_GENERATE;
359     goto ERROR1;
360     }
361    
362     if (config->color || (config->colordepth != 2))
363     psiconv_warn(config,0,psiconv_buffer_length(buf),
364     "All image types except 2-bit greyscale are experimental!");
365    
366    
367 frodo 168 if (!value) {
368     psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section");
369     res = -PSICONV_E_GENERATE;
370     goto ERROR1;
371     }
372    
373 frodo 170 floats.red = value->red;
374     floats.green = value->green;
375     floats.blue = value->blue;
376     floats.length = value->xsize * value->ysize;
377    
378 frodo 176 palet = palet_none;
379     if ((config->color) && (config->redbits == 0) && (config->greenbits == 0) &&\
380     (config->bluebits == 0))
381     switch (config->colordepth) {
382     case 4: palet = palet_color_4; break;
383     case 8: palet = palet_color_8; break;
384     default: palet = palet_none; break;
385     }
386 frodo 170
387     if ((res = psiconv_collect_pixel_data(&ints,value->xsize,
388     value->ysize,floats,
389 frodo 176 config->colordepth,config->color,
390     config->redbits,config->greenbits,
391     config->bluebits,palet)))
392 frodo 168 goto ERROR1;
393 frodo 170
394     if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize,
395     ints,config->colordepth)))
396     goto ERROR2;
397    
398 frodo 175
399 frodo 176 switch (config->colordepth) {
400     case 2:
401     case 4:
402     case 8:
403     encoding = 0x01;
404     if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle)))
405     goto ERROR3;
406     break;
407     case 12:
408     encoding = 0x02;
409     if ((res = psiconv_encode_rle12(config,bytes,&bytes_rle)))
410     goto ERROR3;
411     break;
412     case 16:
413     encoding = 0x03;
414     if ((res = psiconv_encode_rle16(config,bytes,&bytes_rle)))
415     goto ERROR3;
416     break;
417     case 24:
418     encoding = 0x04;
419     if ((res = psiconv_encode_rle24(config,bytes,&bytes_rle)))
420     goto ERROR3;
421     break;
422     default:
423     encoding = 0x00;
424 frodo 175 }
425 frodo 176 if (encoding) {
426     if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) {
427     psiconv_list_free(bytes);
428     bytes = bytes_rle;
429     } else {
430     psiconv_list_free(bytes_rle);
431     encoding = 0x00;
432     }
433     }
434 frodo 175
435     if ((res = psiconv_write_u32(config,buf,
436     0x28+psiconv_list_length(bytes))))
437     goto ERROR3;
438 frodo 170 if ((res = psiconv_write_u32(config,buf,0x28)))
439     goto ERROR3;
440     if ((res = psiconv_write_u32(config,buf,value->xsize)))
441     goto ERROR3;
442     if ((res = psiconv_write_u32(config,buf,value->ysize)))
443     goto ERROR3;
444     if ((res = psiconv_write_length(config,buf,value->pic_xsize)))
445     goto ERROR3;
446     if ((res = psiconv_write_length(config,buf,value->pic_ysize)))
447     goto ERROR3;
448     colordepth = config->colordepth;
449     if ((res = psiconv_write_u32(config,buf,colordepth)))
450     goto ERROR3;
451     if ((res = psiconv_write_u32(config,buf,(config->color?1:0))))
452     goto ERROR3;
453     if ((res = psiconv_write_u32(config,buf,0)))
454     goto ERROR3;
455 frodo 175 if ((res = psiconv_write_u32(config,buf,encoding)))
456 frodo 170 goto ERROR3;
457 frodo 174 if (is_clipart) {
458     if ((res = psiconv_write_u32(config,buf,0xffffffff)))
459     goto ERROR3;
460     if ((res = psiconv_write_u32(config,buf,0x00000044)))
461     goto ERROR3;
462     }
463 frodo 170 for (i = 0; i < psiconv_list_length(bytes); i++) {
464     if (!(byteptr = psiconv_list_get(bytes,i)))
465     goto ERROR3;
466     if ((res = psiconv_write_u8(config,buf,*byteptr)))
467     goto ERROR3;
468 frodo 168 }
469    
470 frodo 170 ERROR3:
471     psiconv_list_free(bytes);
472 frodo 168 ERROR2:
473 frodo 170 psiconv_list_free(ints);
474 frodo 168 ERROR1:
475     return res;
476     }
477    
478     /* Translate the floating point RGB information into pixel values.
479     The palet is optional; without it, we just use the
480     colordepth. With a large palet this is not very fast, but it will do for
481     now. For greyscale pictures, just use the palet. */
482 frodo 170 int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize,
483 frodo 168 const psiconv_pixel_floats_t data,
484 frodo 176 int colordepth,int color,
485     int redbits,int bluebits,int greenbits,
486 frodo 168 const psiconv_pixel_floats_t palet)
487     {
488     int res,x,y,i;
489 frodo 170 psiconv_u32 index,pixel;
490 frodo 176 float p_red,p_green,p_blue,dist,new_dist;
491 frodo 168
492     if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) {
493     res = -PSICONV_E_NOMEM;
494     goto ERROR1;
495     }
496    
497     for (y = 0; y < ysize; y++) {
498     for (x = 0; x < xsize; x++) {
499 frodo 170 index = y*xsize+x;
500 frodo 168 p_red = data.red[index];
501     p_green = data.green[index];
502     p_blue = data.blue[index];
503 frodo 170 if (!palet.length) {
504 frodo 176 if (color)
505     pixel = (((psiconv_u32) (p_red * (1 << redbits) + 0.5))
506     << (greenbits+bluebits)) +
507     (((psiconv_u32) (p_green * (1 << greenbits) + 0.5))
508     << bluebits) +
509     ((psiconv_u32) (p_blue * (1 << bluebits) + 0.5));
510     else
511     pixel = (p_red + p_green + p_blue)/3.0 * (1 << colordepth);
512 frodo 168 } else {
513     dist = 4; /* Max distance is 3, so this is safe */
514     pixel = -1;
515 frodo 170 for (i = 0; i < palet.length; i++) {
516 frodo 168 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) +
517     (p_green - palet.green[i]) * (p_green - palet.green[i]) +
518     (p_blue - palet.blue[i]) * (p_blue - palet.blue[i]);
519     if (new_dist < dist) {
520     pixel = i;
521     dist = new_dist;
522     }
523     }
524     }
525     if ((res = psiconv_list_add(*pixels,&pixel)))
526     goto ERROR2;
527     }
528     }
529     return 0;
530    
531     ERROR2:
532     psiconv_list_free(*pixels);
533     ERROR1:
534     return res;
535     }
536    
537 frodo 170 int psiconv_pixel_data_to_bytes(const psiconv_config config,
538     psiconv_pixel_bytes *bytes, int xsize,
539 frodo 168 int ysize, const psiconv_pixel_ints pixels,
540     int colordepth)
541     {
542     int res;
543     int x,y;
544    
545     psiconv_u32 inputdata;
546     psiconv_u8 outputbyte;
547     psiconv_u32 *pixelptr;
548 frodo 170 int inputbitsleft,outputbitnr,bitsfit,outputbytenr;
549 frodo 168
550    
551     if (!bytes) {
552     psiconv_warn(config,0,0,"NULL pixel data");
553     res = -PSICONV_E_GENERATE;
554     goto ERROR1;
555     }
556     if (!pixels) {
557     psiconv_warn(config,0,0,"NULL pixel data");
558     res = -PSICONV_E_GENERATE;
559     goto ERROR1;
560     }
561     if (psiconv_list_length(pixels) != xsize * ysize) {
562     psiconv_warn(config,0,0,"Pixel number is not correct");
563     res = -PSICONV_E_GENERATE;
564     goto ERROR1;
565     }
566    
567     if (!(*bytes = psiconv_list_new(sizeof(psiconv_u8)))) {
568     res = -PSICONV_E_NOMEM;
569     goto ERROR1;
570     }
571    
572    
573     outputbitnr = 0;
574     outputbyte = 0;
575     for (y = 0; y < ysize; y++) {
576 frodo 170 outputbytenr = 0;
577 frodo 168 for (x = 0; x < xsize; x++) {
578     if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) {
579     psiconv_warn(config,0,0,"Massive internal corruption");
580     res = -PSICONV_E_NOMEM;
581     goto ERROR2;
582     }
583     inputbitsleft = colordepth;
584     inputdata = *pixelptr;
585     while (inputbitsleft) {
586     bitsfit = (inputbitsleft+outputbitnr<=8?inputbitsleft:8-outputbitnr);
587     outputbyte |= (inputdata & ((1 << bitsfit) - 1)) << outputbitnr;
588     inputdata = inputdata >> bitsfit;
589     inputbitsleft -= bitsfit;
590     outputbitnr += bitsfit;
591     if (outputbitnr == 8) {
592     if ((res = psiconv_list_add(*bytes,&outputbyte)))
593     goto ERROR2;
594     outputbitnr = 0;
595     outputbyte = 0;
596 frodo 170 outputbytenr ++;
597 frodo 168 }
598     }
599     }
600 frodo 170 /* Always end lines on a long border */
601 frodo 168 if (outputbitnr != 0) {
602     if ((res = psiconv_list_add(*bytes,&outputbyte)))
603     goto ERROR2;
604     outputbitnr = 0;
605     outputbyte = 0;
606 frodo 170 outputbytenr ++;
607 frodo 168 }
608 frodo 170
609     while (outputbytenr % 0x04) {
610     if ((res = psiconv_list_add(*bytes,&outputbyte)))
611     goto ERROR2;
612     outputbytenr ++;
613     }
614 frodo 168 }
615    
616     return 0;
617    
618     ERROR2:
619     psiconv_list_free(*bytes);
620     ERROR1:
621     return res;
622     }
623 frodo 170
624 frodo 176 /* RLE8 encoding:
625     Marker bytes followed by one or more data bytes.
626     Marker value 0x00-0x7f: repeat the next data byte (marker+1) times
627     Marker value 0xff-0x80: (0x100-marker) data bytes follow */
628 frodo 175 int psiconv_encode_rle8(const psiconv_config config,
629     const psiconv_pixel_bytes plain_bytes,
630     psiconv_pixel_bytes *encoded_bytes)
631     {
632     int res,i,j,len;
633     psiconv_u8 *entry,*next;
634     psiconv_u8 temp;
635    
636     if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry)))) {
637     res = -PSICONV_E_NOMEM;
638     goto ERROR1;
639     }
640    
641     for (i = 0; i < psiconv_list_length(plain_bytes);) {
642     if (!(entry = psiconv_list_get(plain_bytes,i))) {
643     res = -PSICONV_E_NOMEM;
644     goto ERROR2;
645     }
646     if (!(next = psiconv_list_get(plain_bytes,i+1))) {
647     res = -PSICONV_E_NOMEM;
648     goto ERROR2;
649     }
650     if (i == psiconv_list_length(plain_bytes) - 2) {
651     temp = 0xfe;
652     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
653     goto ERROR2;
654     if ((res = psiconv_list_add(*encoded_bytes,entry)))
655     goto ERROR2;
656     if ((res = psiconv_list_add(*encoded_bytes,next)))
657     goto ERROR2;
658     i +=2;
659     } else if (*next == *entry) {
660     len = 0;
661     while ((*next == *entry) &&
662     (i+len + 1 < psiconv_list_length(plain_bytes)) &&
663     len < 0x80) {
664     len ++;
665     if (!(next = psiconv_list_get(plain_bytes,i+len))) {
666     res = -PSICONV_E_NOMEM;
667     goto ERROR2;
668     }
669     }
670     temp = len - 1;
671     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
672     goto ERROR2;
673     if ((res = psiconv_list_add(*encoded_bytes,entry)))
674     goto ERROR2;
675     i += len;
676     } else {
677     len = 1;
678     while ((*next != *entry) &&
679     (i+len+1 < psiconv_list_length(plain_bytes)) &&
680     len < 0x80) {
681     len ++;
682     entry = next;
683     if (!(next = psiconv_list_get(plain_bytes,i+len))) {
684     res = -PSICONV_E_NOMEM;
685     goto ERROR2;
686     }
687     }
688     len --;
689     temp = 0x100 - len;
690     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
691     goto ERROR2;
692     for (j = 0; j < len; j++) {
693     if (!(next = psiconv_list_get(plain_bytes,i+j))) {
694     res = -PSICONV_E_NOMEM;
695     goto ERROR2;
696     }
697     if ((res = psiconv_list_add(*encoded_bytes,next)))
698     goto ERROR2;
699     }
700     i += len;
701     }
702     }
703     return 0;
704    
705     ERROR2:
706     psiconv_list_free(*encoded_bytes);
707     ERROR1:
708     return res;
709     }
710    
711 frodo 176 /* RLE12 encoding:
712     Word based. The 12 least significant bits contain the pixel colors.
713     the 4 most signigicant bits are the number of repetitions minus 1 */
714     int psiconv_encode_rle12(const psiconv_config config,
715     const psiconv_pixel_bytes plain_bytes,
716     psiconv_pixel_bytes *encoded_bytes)
717     {
718     typedef psiconv_list psiconv_word_data; /* of psiconv_u16 */
719     psiconv_word_data data;
720     int res,i,len,location;
721     psiconv_u16 *word_entry,*word_next;
722     psiconv_u16 word_data;
723     psiconv_u8 byte_temp;
724     psiconv_u8 *byte_entry;
725    
726    
727     /* First extract the 12-bit values to encode */
728     if (!(data = psiconv_list_new(sizeof(psiconv_u16)))) {
729     res = -PSICONV_E_NOMEM;
730     goto ERROR1;
731     }
732    
733     for (i = 0; i < psiconv_list_length(plain_bytes); i++) {
734     if (!(byte_entry = psiconv_list_get(plain_bytes,i))) {
735     res = -PSICONV_E_NOMEM;
736     goto ERROR2;
737     }
738     location = 0;
739     if (location == 0) {
740     word_data = *byte_entry;
741     location ++;
742     } else if (location == 1) {
743     word_data = (word_data << 4) + (*byte_entry & 0x0f);
744     if ((res = psiconv_list_add(data,&word_data)))
745     goto ERROR2;
746     word_data = *byte_entry >> 4;
747     location ++;
748     } else {
749     word_data = (word_data << 8) + *byte_entry;
750     if ((res = psiconv_list_add(data,&word_data)))
751     goto ERROR2;
752     location = 0;
753     }
754     }
755    
756     if (!(*encoded_bytes = psiconv_list_new(sizeof(psiconv_u8)))) {
757     res = -PSICONV_E_NOMEM;
758     goto ERROR2;
759     }
760    
761     for (i = 0; i < psiconv_list_length(data);) {
762     if (!(word_entry = psiconv_list_get(data,i))) {
763     res = -PSICONV_E_NOMEM;
764     goto ERROR3;
765     }
766    
767     if (!(word_next = psiconv_list_get(data,i+1))) {
768     res = -PSICONV_E_NOMEM;
769     goto ERROR3;
770     }
771    
772     if (i == psiconv_list_length(data) - 2) {
773     byte_temp = *word_entry && 0xff;
774     if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
775     goto ERROR3;
776     byte_temp = *word_entry >> 8;
777     if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
778     goto ERROR3;
779     byte_temp = *word_next && 0xff;
780     if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
781     goto ERROR3;
782     byte_temp = *word_next >> 8;
783     if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
784     goto ERROR3;
785     i += 2;
786     }
787    
788     len = 0;
789     while ((*word_entry == *word_next) && (len < 16) &&
790     (i+len+1 < psiconv_list_length(data))) {
791     len ++;
792     if (!(word_next = psiconv_list_get(data,i+len))) {
793     res = -PSICONV_E_NOMEM;
794     goto ERROR3;
795     }
796     }
797    
798     byte_temp = *word_entry && 0xff;
799     if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
800     goto ERROR3;
801     byte_temp = (*word_entry >> 8) + ((len - 1) << 4);
802     if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
803     goto ERROR3;
804     i += len;
805     }
806     return 0;
807    
808     ERROR3:
809     psiconv_list_free(*encoded_bytes);
810     ERROR2:
811     psiconv_list_free(data);
812     ERROR1:
813     return res;
814     }
815    
816     /* RLE16 encoding:
817     Marker bytes followed by one or more data words.
818     Marker value 0x00-0x7f: repeat the next data word (marker+1) times
819     Marker value 0xff-0x80: (0x100-marker) data words follow */
820 frodo 175 int psiconv_encode_rle16(const psiconv_config config,
821     const psiconv_pixel_bytes plain_bytes,
822     psiconv_pixel_bytes *encoded_bytes)
823     {
824     int res,i,j,len;
825     psiconv_u8 *entry1,*entry2,*next1,*next2;
826     psiconv_u8 temp;
827    
828     if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) {
829     res = -PSICONV_E_NOMEM;
830     goto ERROR1;
831     }
832    
833     for (i = 0; i < psiconv_list_length(plain_bytes);) {
834     if (!(entry1 = psiconv_list_get(plain_bytes,i))) {
835     res = -PSICONV_E_NOMEM;
836     goto ERROR2;
837     }
838     if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) {
839     res = -PSICONV_E_NOMEM;
840     goto ERROR2;
841     }
842     if (!(next1 = psiconv_list_get(plain_bytes,i+2))) {
843     res = -PSICONV_E_NOMEM;
844     goto ERROR2;
845     }
846     if (!(next2 = psiconv_list_get(plain_bytes,i+3))) {
847     res = -PSICONV_E_NOMEM;
848     goto ERROR2;
849     }
850     if (i == psiconv_list_length(plain_bytes) - 4) {
851     temp = 0xfe;
852     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
853     goto ERROR2;
854     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
855     goto ERROR2;
856     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
857     goto ERROR2;
858     if ((res = psiconv_list_add(*encoded_bytes,next1)))
859     goto ERROR2;
860     if ((res = psiconv_list_add(*encoded_bytes,next2)))
861     goto ERROR2;
862     i +=4;
863     } else if ((*next1 == *entry1) && (*next2 == *entry2)) {
864     len = 0;
865     while (((*next1 == *entry1) && (*next2 == *entry2)) &&
866     (i+2*len + 4 < psiconv_list_length(plain_bytes)) &&
867     len < 0x80) {
868     len ++;
869     if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) {
870     res = -PSICONV_E_NOMEM;
871     goto ERROR2;
872     }
873     if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) {
874     res = -PSICONV_E_NOMEM;
875     goto ERROR2;
876     }
877     }
878     temp = len - 1;
879     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
880     goto ERROR2;
881     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
882     goto ERROR2;
883     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
884     goto ERROR2;
885     i += len*2;
886     } else {
887     len = 1;
888     while (((*next1 != *entry1) || (*next2 != *entry2))&&
889     (i+len*2+4 < psiconv_list_length(plain_bytes)) &&
890     len < 0x80) {
891     len ++;
892     entry1 = next1;
893     entry2 = next2;
894     if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) {
895     res = -PSICONV_E_NOMEM;
896     goto ERROR2;
897     }
898     if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) {
899     res = -PSICONV_E_NOMEM;
900     goto ERROR2;
901     }
902     }
903     len --;
904     temp = 0x100 - len;
905     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
906     goto ERROR2;
907     for (j = 0; j < len; j++) {
908     if (!(next1 = psiconv_list_get(plain_bytes,i+j*2))) {
909     res = -PSICONV_E_NOMEM;
910     goto ERROR2;
911     }
912     if (!(next2 = psiconv_list_get(plain_bytes,i+j*2+1))) {
913     res = -PSICONV_E_NOMEM;
914     goto ERROR2;
915     }
916     if ((res = psiconv_list_add(*encoded_bytes,next1)))
917     goto ERROR2;
918     if ((res = psiconv_list_add(*encoded_bytes,next2)))
919     goto ERROR2;
920     }
921     i += len*2;
922     }
923     }
924     return 0;
925    
926     ERROR2:
927     psiconv_list_free(*encoded_bytes);
928     ERROR1:
929     return res;
930     }
931    
932 frodo 176 /* RLE24 encoding:
933     Marker bytes followed by one or more data byte-triplets.
934     Marker value 0x00-0x7f: repeat the next data byte-triplets (marker+1) times
935     Marker value 0xff-0x80: (0x100-marker) data byte-triplets follow */
936 frodo 175 int psiconv_encode_rle24(const psiconv_config config,
937     const psiconv_pixel_bytes plain_bytes,
938     psiconv_pixel_bytes *encoded_bytes)
939     {
940     int res,i,j,len;
941     psiconv_u8 *entry1,*entry2,*entry3,*next1,*next2,*next3;
942     psiconv_u8 temp;
943    
944     if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) {
945     res = -PSICONV_E_NOMEM;
946     goto ERROR1;
947     }
948    
949     for (i = 0; i < psiconv_list_length(plain_bytes);) {
950     if (!(entry1 = psiconv_list_get(plain_bytes,i))) {
951     res = -PSICONV_E_NOMEM;
952     goto ERROR2;
953     }
954     if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) {
955     res = -PSICONV_E_NOMEM;
956     goto ERROR2;
957     }
958     if (!(entry3 = psiconv_list_get(plain_bytes,i+2))) {
959     res = -PSICONV_E_NOMEM;
960     goto ERROR2;
961     }
962     if (!(next1 = psiconv_list_get(plain_bytes,i+3))) {
963     res = -PSICONV_E_NOMEM;
964     goto ERROR2;
965     }
966     if (!(next2 = psiconv_list_get(plain_bytes,i+4))) {
967     res = -PSICONV_E_NOMEM;
968     goto ERROR2;
969     }
970     if (!(next3 = psiconv_list_get(plain_bytes,i+5))) {
971     res = -PSICONV_E_NOMEM;
972     goto ERROR2;
973     }
974     if (i == psiconv_list_length(plain_bytes) - 6) {
975     temp = 0xfe;
976     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
977     goto ERROR2;
978     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
979     goto ERROR2;
980     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
981     goto ERROR2;
982     if ((res = psiconv_list_add(*encoded_bytes,entry3)))
983     goto ERROR2;
984     if ((res = psiconv_list_add(*encoded_bytes,next1)))
985     goto ERROR2;
986     if ((res = psiconv_list_add(*encoded_bytes,next2)))
987     goto ERROR2;
988     if ((res = psiconv_list_add(*encoded_bytes,next3)))
989     goto ERROR2;
990     i +=4;
991     } else if ((*next1 == *entry1) && (*next2 == *entry2) &&
992     (*next3 == *entry3)) {
993     len = 0;
994     while (((*next1 == *entry1) && (*next2 == *entry2) &&
995     (*next3 == *entry3)) &&
996     (i+3*len + 6 < psiconv_list_length(plain_bytes)) &&
997     len < 0x80) {
998     len ++;
999     if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) {
1000     res = -PSICONV_E_NOMEM;
1001     goto ERROR2;
1002     }
1003     if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) {
1004     res = -PSICONV_E_NOMEM;
1005     goto ERROR2;
1006     }
1007     if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) {
1008     res = -PSICONV_E_NOMEM;
1009     goto ERROR2;
1010     }
1011     }
1012     temp = len - 1;
1013     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
1014     goto ERROR2;
1015     if ((res = psiconv_list_add(*encoded_bytes,entry1)))
1016     goto ERROR2;
1017     if ((res = psiconv_list_add(*encoded_bytes,entry2)))
1018     goto ERROR2;
1019     if ((res = psiconv_list_add(*encoded_bytes,entry3)))
1020     goto ERROR2;
1021     i += len*3;
1022     } else {
1023     len = 1;
1024     while (((*next1 != *entry1) || (*next2 != *entry2) ||
1025     (*next3 != *entry3)) &&
1026     (i+len*3+6 < psiconv_list_length(plain_bytes)) &&
1027     len < 0x80) {
1028     len ++;
1029     entry1 = next1;
1030     entry2 = next2;
1031     entry3 = next3;
1032     if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) {
1033     res = -PSICONV_E_NOMEM;
1034     goto ERROR2;
1035     }
1036     if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) {
1037     res = -PSICONV_E_NOMEM;
1038     goto ERROR2;
1039     }
1040     if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) {
1041     res = -PSICONV_E_NOMEM;
1042     goto ERROR2;
1043     }
1044     }
1045     len --;
1046     temp = 0x100 - len;
1047     if ((res = psiconv_list_add(*encoded_bytes,&temp)))
1048     goto ERROR2;
1049     for (j = 0; j < len; j++) {
1050     if (!(next1 = psiconv_list_get(plain_bytes,i+j*3))) {
1051     res = -PSICONV_E_NOMEM;
1052     goto ERROR2;
1053     }
1054     if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+1))) {
1055     res = -PSICONV_E_NOMEM;
1056     goto ERROR2;
1057     }
1058     if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+2))) {
1059     res = -PSICONV_E_NOMEM;
1060     goto ERROR2;
1061     }
1062     if ((res = psiconv_list_add(*encoded_bytes,next1)))
1063     goto ERROR2;
1064     if ((res = psiconv_list_add(*encoded_bytes,next2)))
1065     goto ERROR2;
1066     if ((res = psiconv_list_add(*encoded_bytes,next3)))
1067     goto ERROR2;
1068     }
1069     i += len*3;
1070     }
1071     }
1072     return 0;
1073    
1074     ERROR2:
1075     psiconv_list_free(*encoded_bytes);
1076     ERROR1:
1077     return res;
1078     }
1079    
1080    
1081 frodo 170 int psiconv_write_sketch_section(const psiconv_config config,
1082     psiconv_buffer buf,
1083 frodo 171 const psiconv_sketch_section value)
1084 frodo 170 {
1085     int res;
1086    
1087     if (!value) {
1088     psiconv_warn(config,0,0,"NULL sketch section");
1089     res = -PSICONV_E_GENERATE;
1090     goto ERROR1;
1091     }
1092    
1093     if ((res = psiconv_write_u16(config,buf,value->displayed_xsize)))
1094     goto ERROR1;
1095     if ((res = psiconv_write_u16(config,buf,value->displayed_ysize)))
1096     goto ERROR1;
1097     if ((res = psiconv_write_u16(config,buf,value->picture_data_x_offset)))
1098     goto ERROR1;
1099     if ((res = psiconv_write_u16(config,buf,value->picture_data_y_offset)))
1100     goto ERROR1;
1101     if ((res = psiconv_write_u16(config,buf,value->displayed_size_x_offset)))
1102     goto ERROR1;
1103     if ((res = psiconv_write_u16(config,buf,value->displayed_size_y_offset)))
1104     goto ERROR1;
1105     if ((res = psiconv_write_u16(config,buf,value->form_xsize)))
1106     goto ERROR1;
1107     if ((res = psiconv_write_u16(config,buf,value->form_ysize)))
1108     goto ERROR1;
1109     if ((res = psiconv_write_u16(config,buf,0x0000)))
1110     goto ERROR1;
1111 frodo 174 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,0)))
1112 frodo 170 goto ERROR1;
1113     if ((res = psiconv_write_u16(config,buf,value->magnification_x * 0x03e8)))
1114     goto ERROR1;
1115     if ((res = psiconv_write_u16(config,buf,value->magnification_y * 0x03e8)))
1116     goto ERROR1;
1117     if ((res = psiconv_write_u32(config,buf,value->cut_left * 0x0c *
1118     value->displayed_xsize)))
1119     goto ERROR1;
1120     if ((res = psiconv_write_u32(config,buf,value->cut_right * 0x0c *
1121     value->displayed_xsize)))
1122     goto ERROR1;
1123     if ((res = psiconv_write_u32(config,buf,value->cut_top * 0x0c *
1124     value->displayed_ysize)))
1125     goto ERROR1;
1126     if ((res = psiconv_write_u32(config,buf,value->cut_bottom * 0x0c *
1127     value->displayed_ysize)))
1128     goto ERROR1;
1129    
1130     ERROR1:
1131     return res;
1132     }
1133 frodo 171
1134 frodo 175 int psiconv_write_clipart_section(const psiconv_config config,
1135     psiconv_buffer buf,
1136     const psiconv_clipart_section value)
1137     {
1138     int res;
1139    
1140    
1141     if (!value) {
1142     psiconv_warn(config,0,psiconv_buffer_length(buf),
1143     "NULL Clipart Section");
1144     res = -PSICONV_E_GENERATE;
1145     goto ERROR;
1146     }
1147     if ((res = psiconv_write_u32(config,buf,PSICONV_ID_CLIPART_ITEM)))
1148     goto ERROR;
1149     if ((res = psiconv_write_u32(config,buf,0x00000002)))
1150     goto ERROR;
1151     if ((res = psiconv_write_u32(config,buf,0x00000000)))
1152     goto ERROR;
1153     if ((res = psiconv_write_u32(config,buf,0x00000000)))
1154     goto ERROR;
1155     if ((res = psiconv_write_u32(config,buf,0x0000000C)))
1156     goto ERROR;
1157     if ((res = psiconv_write_paint_data_section(config,buf,value->picture,1)))
1158     goto ERROR;
1159    
1160     ERROR:
1161     return res;
1162     }
1163    
1164 frodo 171 int psiconv_write_jumptable_section(const psiconv_config config,
1165     psiconv_buffer buf,
1166     const psiconv_jumptable_section value)
1167     {
1168     int res,i;
1169     psiconv_u32 *offset_ptr;
1170    
1171    
1172     if (!value) {
1173     psiconv_warn(config,0,psiconv_buffer_length(buf),
1174     "NULL Jumptable Section");
1175     res = -PSICONV_E_GENERATE;
1176     goto ERROR;
1177     }
1178     if ((res = psiconv_write_u32(config,buf,psiconv_list_length(value))))
1179     goto ERROR;
1180     for (i = 0; i < psiconv_list_length(value); i++) {
1181     if (!(offset_ptr = psiconv_list_get(value,i))) {
1182     psiconv_warn(config,0,psiconv_buffer_length(buf),
1183     "Massive memory corruption");
1184     res = -PSICONV_E_NOMEM;
1185     goto ERROR;
1186     }
1187     if ((res = psiconv_write_offset(config,buf,*offset_ptr)))
1188     goto ERROR;
1189     }
1190    
1191     ERROR:
1192     return res;
1193     }
1194 frodo 174

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