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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 176 - (show annotations)
Tue Dec 2 19:47:47 2003 UTC (16 years, 1 month 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 /*
2
3 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 #include "list.h"
27
28 #ifdef DMALLOC
29 #include <dmalloc.h>
30 #endif
31
32 typedef psiconv_list psiconv_pixel_bytes; /* psiconv_u8 */
33
34 typedef psiconv_list psiconv_pixel_ints; /* of psiconv_u32 */
35
36 typedef struct psiconv_pixel_float_s
37 {
38 psiconv_u32 length;
39 float *red;
40 float *green;
41 float *blue;
42 } psiconv_pixel_floats_t;
43
44 static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,
45 int xsize,int ysize,
46 const psiconv_pixel_floats_t data,
47 int colordepth,int color,
48 int redbits,int greenbits,int bluebits,
49 const psiconv_pixel_floats_t palet);
50 static int psiconv_pixel_data_to_bytes(const psiconv_config config,
51 psiconv_pixel_bytes *bytes, int xsize,
52 int ysize, const psiconv_pixel_ints pixels,
53 int colordepth);
54 static int psiconv_encode_rle8(const psiconv_config config,
55 const psiconv_pixel_bytes plain_bytes,
56 psiconv_pixel_bytes *encoded_bytes);
57 static int psiconv_encode_rle12(const psiconv_config config,
58 const psiconv_pixel_bytes plain_bytes,
59 psiconv_pixel_bytes *encoded_bytes);
60 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
67 #define PALET_NONE_LEN 0
68
69 psiconv_pixel_floats_t palet_none =
70 {
71 PALET_NONE_LEN,
72 NULL,
73 NULL,
74 NULL
75 };
76
77 #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 {
101 PALET_COLOR_4_LEN,
102 palet_color_4_red,
103 palet_color_4_green,
104 palet_color_4_blue,
105 };
106
107 #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 {
311 PALET_COLOR_8_LEN,
312 palet_color_8_red,
313 palet_color_8_green,
314 palet_color_8_blue,
315 };
316
317 int psiconv_write_paint_data_section(const psiconv_config config,
318 psiconv_buffer buf,
319 const psiconv_paint_data_section value,
320 int is_clipart)
321 {
322 int res,colordepth,i;
323 psiconv_pixel_ints ints;
324 psiconv_pixel_floats_t floats,palet;
325 psiconv_list bytes,bytes_rle;
326 psiconv_u8 *byteptr,encoding;
327
328 /* 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 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 floats.red = value->red;
374 floats.green = value->green;
375 floats.blue = value->blue;
376 floats.length = value->xsize * value->ysize;
377
378 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
387 if ((res = psiconv_collect_pixel_data(&ints,value->xsize,
388 value->ysize,floats,
389 config->colordepth,config->color,
390 config->redbits,config->greenbits,
391 config->bluebits,palet)))
392 goto ERROR1;
393
394 if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize,
395 ints,config->colordepth)))
396 goto ERROR2;
397
398
399 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 }
425 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
435 if ((res = psiconv_write_u32(config,buf,
436 0x28+psiconv_list_length(bytes))))
437 goto ERROR3;
438 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 if ((res = psiconv_write_u32(config,buf,encoding)))
456 goto ERROR3;
457 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 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 }
469
470 ERROR3:
471 psiconv_list_free(bytes);
472 ERROR2:
473 psiconv_list_free(ints);
474 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 int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize,
483 const psiconv_pixel_floats_t data,
484 int colordepth,int color,
485 int redbits,int bluebits,int greenbits,
486 const psiconv_pixel_floats_t palet)
487 {
488 int res,x,y,i;
489 psiconv_u32 index,pixel;
490 float p_red,p_green,p_blue,dist,new_dist;
491
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 index = y*xsize+x;
500 p_red = data.red[index];
501 p_green = data.green[index];
502 p_blue = data.blue[index];
503 if (!palet.length) {
504 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 } else {
513 dist = 4; /* Max distance is 3, so this is safe */
514 pixel = -1;
515 for (i = 0; i < palet.length; i++) {
516 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 int psiconv_pixel_data_to_bytes(const psiconv_config config,
538 psiconv_pixel_bytes *bytes, int xsize,
539 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 int inputbitsleft,outputbitnr,bitsfit,outputbytenr;
549
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 outputbytenr = 0;
577 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 outputbytenr ++;
597 }
598 }
599 }
600 /* Always end lines on a long border */
601 if (outputbitnr != 0) {
602 if ((res = psiconv_list_add(*bytes,&outputbyte)))
603 goto ERROR2;
604 outputbitnr = 0;
605 outputbyte = 0;
606 outputbytenr ++;
607 }
608
609 while (outputbytenr % 0x04) {
610 if ((res = psiconv_list_add(*bytes,&outputbyte)))
611 goto ERROR2;
612 outputbytenr ++;
613 }
614 }
615
616 return 0;
617
618 ERROR2:
619 psiconv_list_free(*bytes);
620 ERROR1:
621 return res;
622 }
623
624 /* 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 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 /* 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 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 /* 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 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 int psiconv_write_sketch_section(const psiconv_config config,
1082 psiconv_buffer buf,
1083 const psiconv_sketch_section value)
1084 {
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 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,0)))
1112 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
1134 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 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@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26