]>
Commit | Line | Data |
---|---|---|
14c7c974 A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
4f6e3300 A |
6 | * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.1 (the "License"). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
14c7c974 A |
13 | * |
14 | * The Original Code and all software distributed under the License are | |
4f6e3300 | 15 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
14c7c974 A |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
4f6e3300 A |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License. | |
14c7c974 A |
21 | * |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | #import <stdio.h> | |
25 | #import <sys/param.h> | |
26 | #import <appkit/NXBitmapImageRep.h> | |
27 | #import "BooterBitmap.h" | |
28 | #import "bitmap.h" | |
29 | ||
30 | @implementation BooterBitmap | |
31 | ||
32 | - init | |
33 | { | |
34 | bg_color = BG_COLOR; | |
35 | return [super init]; | |
36 | } | |
37 | ||
38 | - free | |
39 | { | |
40 | if (bitmapImageRep) [bitmapImageRep free]; | |
41 | if (packed_planes[0]) free(packed_planes[0]); | |
42 | if (packed_planes[1]) free(packed_planes[1]); | |
43 | return [super free]; | |
44 | } | |
45 | ||
46 | - initFromTiffFile: (char *)inputFileName; | |
47 | { | |
48 | [self init]; | |
49 | filename = inputFileName; | |
50 | bitmapImageRep = [[NXBitmapImageRep alloc] | |
51 | initFromFile:inputFileName]; | |
52 | if (bitmapImageRep == nil) { | |
53 | fprintf(stderr, "BooterBitmap: couldn't load tiff file %s\n",filename); | |
54 | return nil; | |
55 | } | |
56 | if ([bitmapImageRep numPlanes] - [bitmapImageRep hasAlpha] != 1) { | |
57 | fprintf(stderr, | |
58 | "BooterBitmap: can't deal with more than one input plane (excluding alpha)\n"); | |
59 | return nil; | |
60 | } | |
61 | if ([bitmapImageRep bitsPerPixel] != BITS_PER_PIXEL) { | |
62 | fprintf(stderr, | |
63 | "BooterBitmap: can't deal with anything but %d bits per pixel\n", | |
64 | BITS_PER_PIXEL); | |
65 | return nil; | |
66 | } | |
67 | [bitmapImageRep getDataPlanes:planes]; | |
68 | width = [bitmapImageRep pixelsWide]; | |
69 | height = [bitmapImageRep pixelsHigh]; | |
70 | bytes_per_plane = [bitmapImageRep bytesPerPlane]; | |
71 | return self; | |
72 | } | |
73 | ||
74 | - (BOOL)_allocPlanes | |
75 | { | |
76 | if (packed_planes[0]) free(packed_planes[0]); | |
77 | if (packed_planes[1]) free(packed_planes[1]); | |
78 | packed_planes[0] = (unsigned char *)malloc(bytes_per_plane / NPLANES); | |
79 | packed_planes[1] = (unsigned char *)malloc(bytes_per_plane / NPLANES); | |
80 | if (packed_planes[0] == 0 || packed_planes[1] == 0) | |
81 | return NO; | |
82 | else | |
83 | return YES; | |
84 | } | |
85 | ||
86 | - (BOOL)_convertPlanes | |
87 | { | |
88 | int plane, i, j, outbit, index; | |
89 | unsigned char *pp, *alpha, *plane_tmp, *data; | |
90 | unsigned char alphabyte, inbyte, outbyte; | |
91 | int new_bytes_per_plane, bytes_per_row; | |
92 | TIFF tif; | |
93 | int doPack = 1; | |
94 | ||
95 | startOver: | |
96 | if ([self _allocPlanes] == NO) | |
97 | return NO; | |
98 | plane_tmp = (unsigned char *)malloc(bytes_per_plane / NPLANES); | |
99 | for (plane = 0; plane < NPLANES; plane++) { | |
100 | int col; | |
101 | ||
102 | data = planes[0]; | |
103 | alpha = planes[1]; | |
104 | pp = plane_tmp; | |
105 | ||
106 | bytes_per_row = bytes_per_plane / height; | |
107 | ||
108 | for(i=0; i < height; i++) { | |
109 | for(j = outbyte = col = 0, outbit = 7; j < width; j++) { | |
110 | if ((j % (8 / NPLANES)) == 0) { | |
111 | index = (i * bytes_per_row) + (j / (8 / NPLANES)); | |
112 | inbyte = data[index]; | |
113 | if (alpha) | |
114 | alphabyte = alpha[index]; | |
115 | } | |
116 | if (alpha && ((alphabyte & 0xC0) == 0)) { | |
117 | outbyte |= | |
118 | ((bg_color & (1 << plane)) >> plane) << outbit; | |
119 | } else { | |
120 | outbyte |= | |
121 | ((((inbyte & 0xC0) >> (8 - NPLANES)) & (1 << plane)) | |
122 | >> plane) << outbit; | |
123 | } | |
124 | if (outbit-- == 0) { | |
125 | *pp++ = outbyte; | |
126 | outbyte = 0; | |
127 | outbit = 7; | |
128 | } | |
129 | inbyte <<= NPLANES; | |
130 | alphabyte <<= NPLANES; | |
131 | } | |
132 | if (outbit < 7) | |
133 | *pp++ = outbyte; | |
134 | } | |
135 | bytes_per_row = (width + 7) / 8; | |
136 | new_bytes_per_plane = pp - plane_tmp; | |
137 | ||
138 | tif.tif_rawdata = tif.tif_rawcp = packed_planes[plane]; | |
139 | tif.tif_rawdatasize = new_bytes_per_plane; | |
140 | tif.tif_rawcc = 0; | |
141 | tif.tif_row = 0; | |
142 | pp = plane_tmp; | |
143 | if (doPack) { | |
144 | for (i=0; i < height; i++) { | |
145 | if (PackBitsEncode(&tif, pp, bytes_per_row, 0) == -1) { | |
146 | // packed data is bigger than raw data! | |
147 | doPack = 0; | |
148 | free(plane_tmp); | |
149 | goto startOver; | |
150 | } | |
151 | pp += bytes_per_row; | |
152 | } | |
153 | } else { | |
154 | bcopy(plane_tmp, packed_planes[plane], new_bytes_per_plane); | |
155 | tif.tif_rawcc = new_bytes_per_plane; | |
156 | } | |
157 | plane_len[plane] = tif.tif_rawcc; | |
158 | } | |
159 | free(plane_tmp); | |
160 | packed = doPack; | |
161 | return YES; | |
162 | } | |
163 | ||
164 | ||
165 | - (BOOL) writeAsCFile: (char *)output_name | |
166 | { | |
167 | char buf[MAXPATHLEN], oname_buf[MAXPATHLEN]; | |
168 | char *name; | |
169 | FILE *bhfile, *hfile; | |
170 | int i, plane; | |
171 | ||
172 | if (output_name) { | |
173 | strcpy(oname_buf, output_name); | |
174 | } else if (filename) { | |
175 | strcpy(oname_buf, filename); | |
176 | buf[strlen(buf) - strlen(".tiff")] = '\0'; | |
177 | } else { | |
178 | fprintf(stderr,"BooterBitmap writeAsCFile: no filename\n"); | |
179 | return NO; | |
180 | } | |
181 | output_name = oname_buf; | |
182 | if ([self _convertPlanes] == NO) { | |
183 | fprintf(stderr,"_convertPlanes failed\n"); | |
184 | return NO; | |
185 | } | |
186 | ||
187 | name = (char *)strrchr(output_name, '/'); | |
188 | if (name == NULL) | |
189 | name = output_name; | |
190 | else | |
191 | name++; | |
192 | sprintf(buf, "%s_bitmap.h",output_name); | |
193 | bhfile = fopen(buf,"w"); | |
194 | if (bhfile == 0) { | |
195 | fprintf(stderr,"Couldn't open %s for writing\n",buf); | |
196 | perror("open"); | |
197 | return NO; | |
198 | } | |
199 | sprintf(buf,"%s.h",output_name); | |
200 | hfile = fopen(buf,"w"); | |
201 | if (hfile == 0) { | |
202 | fprintf(stderr,"Couldn't open %s for writing\n",buf); | |
203 | perror("open"); | |
204 | return NO; | |
205 | } | |
206 | ||
207 | for(plane = 0; plane < NPLANES; plane++) { | |
208 | int col = 0; | |
209 | unsigned char *pp; | |
210 | fprintf(bhfile,"unsigned char %s_bitmap_plane_%d[] =\n",name,plane); | |
211 | fprintf(bhfile," {\n"); | |
212 | fprintf(bhfile,"// plane %d\n",plane); | |
213 | pp = packed_planes[plane]; | |
214 | for (i=0; i < plane_len[plane]; i++) { | |
215 | fprintf(bhfile,"0x%02x, ",*pp++); | |
216 | if ((col += 7) > 70) { | |
217 | col = 0; | |
218 | fprintf(bhfile,"\n"); | |
219 | } | |
220 | } | |
221 | fprintf(bhfile,"};\n"); | |
222 | } | |
223 | ||
224 | fprintf(bhfile,"struct bitmap %s_bitmap = {\n",name); | |
225 | fprintf(bhfile,"%d,\t// packed\n",packed); | |
226 | fprintf(bhfile,"%d,\t// bytes_per_plane\n",bytes_per_plane / NPLANES); | |
227 | fprintf(bhfile,"%d,\t// bytes_per_row\n", (width + 7) / 8); | |
228 | fprintf(bhfile,"%d,\t// bits per pixel\n", 1); | |
229 | fprintf(bhfile,"%d,\t// width\n", width); | |
230 | fprintf(bhfile,"%d,\t// height\n", height); | |
231 | fprintf(bhfile,"{\n"); | |
232 | fprintf(bhfile," %d,\n", plane_len[0]); | |
233 | fprintf(bhfile," %d,\n", plane_len[1]); | |
234 | fprintf(bhfile,"},\n"); | |
235 | fprintf(bhfile,"{\n"); | |
236 | fprintf(bhfile," %s_bitmap_plane_0,\n", name); | |
237 | fprintf(bhfile," %s_bitmap_plane_1\n", name); | |
238 | fprintf(bhfile,"}\n"); | |
239 | fprintf(bhfile,"};\n"); | |
240 | fprintf(bhfile,"\n#define %s_bitmap_WIDTH\t%d\n", name, width); | |
241 | fprintf(bhfile,"#define %s_bitmap_HEIGHT\t%d\n", name, height); | |
242 | fclose(bhfile); | |
243 | fprintf(hfile,"extern struct bitmap %s_bitmap;\n",name); | |
244 | fprintf(hfile,"\n#define %s_bitmap_WIDTH\t%d\n", name, width); | |
245 | fprintf(hfile,"#define %s_bitmap_HEIGHT\t%d\n", name, height); | |
246 | fclose(bhfile); | |
247 | return YES; | |
248 | } | |
249 | ||
250 | - (BOOL) writeAsBinaryFile: (char *)outputFile | |
251 | { | |
252 | struct bitmap bd; | |
253 | char buf[MAXPATHLEN]; | |
254 | FILE *file; | |
255 | ||
256 | if (outputFile) { | |
257 | strcpy(buf, outputFile); | |
258 | } else if (filename) { | |
259 | strcpy(buf, filename); | |
260 | } else { | |
261 | fprintf(stderr,"writeAsBinaryFile: no filename\n"); | |
262 | return NO; | |
263 | } | |
264 | strcat(buf, ".image"); | |
265 | file = fopen(buf, "w"); | |
266 | if (file == NULL) { | |
267 | fprintf(stderr, "writeAsBinaryFile: couldn't open output file %s\n", | |
268 | buf); | |
269 | return NO; | |
270 | } | |
271 | if ([self _convertPlanes] == NO) { | |
272 | fprintf(stderr,"_convertPlanes failed\n"); | |
273 | return NO; | |
274 | } | |
275 | bd.packed = packed; | |
276 | bd.bytes_per_plane = bytes_per_plane / NPLANES; | |
277 | bd.bytes_per_row = (width + 7) / 8; | |
278 | bd.bits_per_pixel = 1; | |
279 | bd.width = width; | |
280 | bd.height = height; | |
281 | bd.plane_len[0] = plane_len[0]; | |
282 | bd.plane_len[1] = plane_len[1]; | |
283 | bd.plane_data[0] = bd.plane_data[1] = 0; | |
284 | if (fwrite(&bd, sizeof(bd), 1, file) < 1) goto error; | |
285 | if (fwrite(packed_planes[0], plane_len[0], 1, file) < 1) goto error; | |
286 | if (fwrite(packed_planes[1], plane_len[1], 1, file) < 1) goto error; | |
287 | fclose(file); | |
288 | return YES; | |
289 | error: | |
290 | perror("fwrite"); | |
291 | return NO; | |
292 | } | |
293 | ||
294 | ||
295 | - (int) width | |
296 | { | |
297 | return width; | |
298 | } | |
299 | ||
300 | - (int) height | |
301 | { | |
302 | return height; | |
303 | } | |
304 | ||
305 | - (int) setWidth: (int)newWidth | |
306 | { | |
307 | return width = newWidth; | |
308 | } | |
309 | ||
310 | - (int) setHeight: (int)newHeight | |
311 | { | |
312 | return height = newHeight; | |
313 | } | |
314 | ||
315 | - (int) bgColor | |
316 | { | |
317 | return bg_color; | |
318 | } | |
319 | ||
320 | - (int) setBgColor: (int)newColor | |
321 | { | |
322 | return bg_color = newColor; | |
323 | } | |
324 | ||
325 | - (BOOL) setTwoBitsPerPixelColorData: (unsigned char *)bits; | |
326 | { | |
327 | planes[0] = bits; | |
328 | return YES; | |
329 | } | |
330 | ||
331 | - (BOOL) setTwoBitsPerPixelAlphaData: (unsigned char *)bits; | |
332 | { | |
333 | planes[1] = bits; | |
334 | return YES; | |
335 | } | |
336 | ||
337 | - (unsigned char *) twoBitsPerPixelColorData | |
338 | { | |
339 | return planes[0]; | |
340 | } | |
341 | ||
342 | - (unsigned char *) twoBitsPerPixelAlphaData | |
343 | { | |
344 | return planes[1]; | |
345 | } | |
346 | ||
347 | - (int) colorDataBytes | |
348 | { | |
349 | return bytes_per_plane; | |
350 | } | |
351 | ||
352 | - (int) setColorDataBytes: (int)bpp | |
353 | { | |
354 | return bytes_per_plane = bpp; | |
355 | } | |
356 | ||
357 | - (char *)filename | |
358 | { | |
359 | return filename; | |
360 | } | |
361 | ||
362 | ||
363 | @end |