source: trunk/JPGPROC/source/gbmsrc/gbmbpp.c@ 2

Last change on this file since 2 was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 16.8 KB
Line 
1/*
2
3gbmbpp.c - Change bits per pixel in a General Bitmap
4
5*/
6
7/*...sincludes:0:*/
8#include <stdio.h>
9#include <ctype.h>
10#include <string.h>
11#include <stddef.h>
12#include <stdlib.h>
13#include <stdarg.h>
14#if defined(AIX) || defined(LINUX) || defined(MAC)
15#include <unistd.h>
16#else
17#include <io.h>
18#endif
19#include <fcntl.h>
20#ifdef MAC
21#include <types.h>
22#include <stat.h>
23#else
24#include <sys/types.h>
25#include <sys/stat.h>
26#endif
27#ifndef O_BINARY
28#define O_BINARY 0
29#endif
30#include "gbm.h"
31#include "gbmerr.h"
32#include "gbmtrunc.h"
33#include "gbmht.h"
34#include "gbmhist.h"
35#include "gbmmcut.h"
36
37/*...vgbm\46\h:0:*/
38/*...vgbmerr\46\h:0:*/
39/*...vgbmtrunc\46\h:0:*/
40/*...vgbmht\46\h:0:*/
41/*...vgbmhist\46\h:0:*/
42/*...vgbmmcut\46\h:0:*/
43/*...e*/
44
45static char progname[] = "gbmbpp";
46
47/*...sfatal:0:*/
48static void fatal(const char *fmt, ...)
49 {
50 va_list vars;
51 char s[256+1];
52
53 va_start(vars, fmt);
54 vsprintf(s, fmt, vars);
55 va_end(vars);
56 fprintf(stderr, "%s: %s\n", progname, s);
57 exit(1);
58 }
59/*...e*/
60/*...susage:0:*/
61static void usage(void)
62 {
63 int ft, n_ft;
64
65 fprintf(stderr, "usage: %s [-m map] [-e] [-hN] [-p fnp.ext{,opt}]\n", progname);
66 fprintf(stderr, " [--] fn1.ext{,opt} [fn2.ext{,opt}]\n");
67 fprintf(stderr, "flags: -m map mapping to perform (default 7x8x4)\n");
68 fprintf(stderr, " bw black and white\n");
69 fprintf(stderr, " vga 16 colour VGA\n");
70 fprintf(stderr, " 8 8 colour (in 4 bit file)\n");
71 fprintf(stderr, " 4g 4 bit greyscale\n");
72 fprintf(stderr, " 7x8x4 7 levels red, 8 green, 4 blue 8514/A\n");
73 fprintf(stderr, " 6x6x6 6 levels red, 6 green, 6 blue\n");
74 fprintf(stderr, " 8g 8 bit greyscale\n");
75 fprintf(stderr, " tripel 64 reds, 64 greens, 64 blues tripel\n");
76 fprintf(stderr, " pal1bpp map to 1bpp, palette specified via -p\n");
77 fprintf(stderr, " pal4bpp map to 4bpp, palette specified via -p\n");
78 fprintf(stderr, " pal8bpp map to 8bpp, palette specified via -p\n");
79 fprintf(stderr, " freqR:G:B:N keep R red, G green, b blue bits, and map\n");
80 fprintf(stderr, " to N most used colours in 8 bit palette\n");
81 fprintf(stderr, " mcutN median cut to N colours\n");
82 fprintf(stderr, " R:G:B keep R red, G green, B blue bits\n");
83 fprintf(stderr, " -e enable error-diffusion (default is to truncate)\n");
84 fprintf(stderr, " -e only with -m bw, vga, 4g, 7x8x4, 6x6x6, no -h\n");
85 fprintf(stderr, " -h enable halftoning (default is to truncate)\n");
86 fprintf(stderr, " -h only with -m 7x8x4, 6x6x6, 8, vga or R:G:B, no -e\n");
87 fprintf(stderr, " N is a halftoning algorithm number (default 0)\n");
88 fprintf(stderr, " -p fnp.ext{,opt} palette is taken from this bitmap\n");
89 fprintf(stderr, " fn1.ext{,opt} input filename (with any format specific options)\n");
90 fprintf(stderr, " fn2.ext{,opt} optional output filename (or use fn1 if not present)\n");
91 fprintf(stderr, " ext's are used to deduce desired bitmap file formats\n");
92
93 gbm_init();
94 gbm_query_n_filetypes(&n_ft);
95 for ( ft = 0; ft < n_ft; ft++ )
96 {
97 GBMFT gbmft;
98
99 gbm_query_filetype(ft, &gbmft);
100 fprintf(stderr, " %s when ext in [%s]\n",
101 gbmft.short_name, gbmft.extensions);
102 }
103 gbm_deinit();
104
105 fprintf(stderr, " opt's bitmap format specific options\n");
106
107 exit(1);
108 }
109/*...e*/
110/*...ssame:0:*/
111static BOOLEAN same(const char *s1, const char *s2, int n)
112 {
113 for ( ; n--; s1++, s2++ )
114 if ( tolower(*s1) != tolower(*s2) )
115 return FALSE;
116 return TRUE;
117 }
118/*...e*/
119/*...smain:0:*/
120/*...smapinfos:0:*/
121#define CVT_BW 0
122#define CVT_VGA 1
123#define CVT_8 2
124#define CVT_4G 3
125#define CVT_784 4
126#define CVT_666 5
127#define CVT_8G 6
128#define CVT_TRIPEL 7
129#define CVT_PAL1BPP 8
130#define CVT_PAL4BPP 9
131#define CVT_PAL8BPP 10
132#define CVT_RGB 11
133#define CVT_FREQ 12
134#define CVT_MCUT 13
135#define CVT_ERRDIFF 0x4000
136#define CVT_HALFTONE 0x2000
137
138typedef struct { char *name; int m; int dest_bpp; } MAPINFO;
139
140static MAPINFO mapinfos[] =
141 {
142 "bw", CVT_BW, 1,
143 "vga", CVT_VGA, 4,
144 "8", CVT_8, 4,
145 "4g", CVT_4G, 4,
146 "7x8x4", CVT_784, 8,
147 "6x6x6", CVT_666, 8,
148 "8g", CVT_8G, 8,
149 "tripel", CVT_TRIPEL, 8,
150 "pal1bpp", CVT_PAL1BPP, 1,
151 "pal4bpp", CVT_PAL4BPP, 4,
152 "pal8bpp", CVT_PAL8BPP, 8,
153 };
154
155#define N_MAPINFOS (sizeof(mapinfos)/sizeof(mapinfos[0]))
156/*...e*/
157/*...sget_masks:0:*/
158/*
159Returns TRUE if a set of masks given at map.
160Also sets *rm, *gm, *bm from these.
161Else returns FALSE.
162*/
163
164static byte mask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
165
166static BOOLEAN get_masks(char *map, byte *rm, byte *gm, byte *bm)
167 {
168 if ( map[0] < '0' || map[0] > '8' ||
169 map[1] != ':' ||
170 map[2] < '0' || map[2] > '8' ||
171 map[3] != ':' ||
172 map[4] < '0' || map[4] > '8' )
173 return FALSE;
174
175 *rm = mask[map[0] - '0'];
176 *gm = mask[map[2] - '0'];
177 *bm = mask[map[4] - '0'];
178 return TRUE;
179 }
180/*...e*/
181/*...sget_pal:0:*/
182static void get_pal(const char *pal, GBMRGB *gbmrgb, int bpp, int *ncols)
183 {
184 char fn_pal[500+1], *opt_pal;
185 int fd, ft_pal, i;
186 GBM gbm;
187 GBM_ERR rc;
188
189 if ( pal == NULL )
190 fatal("palette file must be specified");
191
192 strcpy(fn_pal, pal);
193 if ( (opt_pal = strchr(fn_pal, ',')) != NULL )
194 *opt_pal++ = '\0';
195 else
196 opt_pal = "";
197
198 if ( gbm_guess_filetype(fn_pal, &ft_pal) != GBM_ERR_OK )
199 fatal("can't guess bitmap file format for %s", fn_pal);
200
201 if ( (fd = gbm_io_open(fn_pal, O_RDONLY|O_BINARY)) == -1 )
202 fatal("can't open %s", fn_pal);
203
204 if ( (rc = gbm_read_header(fn_pal, fd, ft_pal, &gbm, opt_pal)) != GBM_ERR_OK )
205 {
206 gbm_io_close(fd);
207 fatal("can't read header of %s: %s", fn_pal, gbm_err(rc));
208 }
209
210 if ( gbm.bpp > 8 )
211 {
212 gbm_io_close(fd);
213 fatal("bitmap %s should contain a palette", fn_pal);
214 }
215
216 if ( gbm.bpp > bpp )
217 {
218 gbm_io_close(fd);
219 fatal("bitmap %s has too many colours in palette for chosen mapping", fn_pal);
220 }
221
222 /* Pre-initialise palette with medium grey */
223 for ( i = 0; i < (1<<bpp); i++ )
224 gbmrgb[i].r =
225 gbmrgb[i].g =
226 gbmrgb[i].b = 0x80;
227
228 if ( (rc = gbm_read_palette(fd, ft_pal, &gbm, gbmrgb)) != GBM_ERR_OK )
229 {
230 gbm_io_close(fd);
231 fatal("can't read palette of %s: %s", fn_pal, gbm_err(rc));
232 }
233
234 gbm_io_close(fd);
235
236 *ncols = ( 1 << gbm.bpp );
237 }
238/*...e*/
239/*...sexpand_to_24bit:0:*/
240static void expand_to_24bit(GBM *gbm, GBMRGB *gbmrgb, byte **data)
241 {
242 int stride = ((gbm->w * gbm->bpp + 31)/32) * 4;
243 int new_stride = ((gbm->w * 3 + 3) & ~3);
244 int bytes, y;
245 byte *new_data;
246
247 if ( gbm->bpp == 24 )
248 return;
249
250 bytes = new_stride * gbm->h;
251 if ( (new_data = malloc((size_t) bytes)) == NULL )
252 fatal("out of memory allocating %d bytes", bytes);
253
254 for ( y = 0; y < gbm->h; y++ )
255 {
256 byte *src = *data + y * stride;
257 byte *dest = new_data + y * new_stride;
258 int x;
259
260 switch ( gbm->bpp )
261 {
262/*...s1:24:*/
263case 1:
264 {
265 byte c;
266
267 for ( x = 0; x < gbm->w; x++ )
268 {
269 if ( (x & 7) == 0 )
270 c = *src++;
271 else
272 c <<= 1;
273
274 *dest++ = gbmrgb[c >> 7].b;
275 *dest++ = gbmrgb[c >> 7].g;
276 *dest++ = gbmrgb[c >> 7].r;
277 }
278 }
279 break;
280/*...e*/
281/*...s4:24:*/
282case 4:
283 for ( x = 0; x + 1 < gbm->w; x += 2 )
284 {
285 byte c = *src++;
286
287 *dest++ = gbmrgb[c >> 4].b;
288 *dest++ = gbmrgb[c >> 4].g;
289 *dest++ = gbmrgb[c >> 4].r;
290 *dest++ = gbmrgb[c & 15].b;
291 *dest++ = gbmrgb[c & 15].g;
292 *dest++ = gbmrgb[c & 15].r;
293 }
294
295 if ( x < gbm->w )
296 {
297 byte c = *src;
298
299 *dest++ = gbmrgb[c >> 4].b;
300 *dest++ = gbmrgb[c >> 4].g;
301 *dest++ = gbmrgb[c >> 4].r;
302 }
303 break;
304/*...e*/
305/*...s8:24:*/
306case 8:
307 for ( x = 0; x < gbm->w; x++ )
308 {
309 byte c = *src++;
310
311 *dest++ = gbmrgb[c].b;
312 *dest++ = gbmrgb[c].g;
313 *dest++ = gbmrgb[c].r;
314 }
315 break;
316/*...e*/
317 }
318 }
319 free(*data);
320 *data = new_data;
321 gbm->bpp = 24;
322 }
323/*...e*/
324/*...sto_grey_pal:0:*/
325static void to_grey_pal(GBMRGB *gbmrgb)
326 {
327 int i;
328
329 for ( i = 0; i < 0x100; i++ )
330 gbmrgb[i].r =
331 gbmrgb[i].g =
332 gbmrgb[i].b = (byte) i;
333 }
334/*...e*/
335/*...sto_grey:0:*/
336static void to_grey(GBM *gbm, const byte *src_data, byte *dest_data)
337 {
338 int src_stride = ((gbm->w * 3 + 3) & ~3);
339 int dest_stride = ((gbm->w + 3) & ~3);
340 int y;
341
342 for ( y = 0; y < gbm->h; y++ )
343 {
344 const byte *src = src_data;
345 byte *dest = dest_data;
346 int x;
347
348 for ( x = 0; x < gbm->w; x++ )
349 {
350 byte b = *src++;
351 byte g = *src++;
352 byte r = *src++;
353
354 *dest++ = (byte) (((word) r * 77U + (word) g * 150U + (word) b * 29U) >> 8);
355 }
356
357 src_data += src_stride;
358 dest_data += dest_stride;
359 }
360 gbm->bpp = 8;
361 }
362/*...e*/
363/*...stripel_pal:0:*/
364static void tripel_pal(GBMRGB *gbmrgb)
365 {
366 int i;
367
368 memset(gbmrgb, 0, 0x100 * sizeof(GBMRGB));
369
370 for ( i = 0; i < 0x40; i++ )
371 {
372 gbmrgb[i ].r = (byte) (i << 2);
373 gbmrgb[i + 0x40].g = (byte) (i << 2);
374 gbmrgb[i + 0x80].b = (byte) (i << 2);
375 }
376 }
377/*...e*/
378/*...stripel:0:*/
379static void tripel(GBM *gbm, const byte *src_data, byte *dest_data)
380 {
381 int src_stride = ((gbm->w * 3 + 3) & ~3);
382 int dest_stride = ((gbm->w + 3) & ~3);
383 int y;
384
385 for ( y = 0; y < gbm->h; y++ )
386 {
387 const byte *src = src_data;
388 byte *dest = dest_data;
389 int x;
390
391 for ( x = 0; x < gbm->w; x++ )
392 {
393 byte b = *src++;
394 byte g = *src++;
395 byte r = *src++;
396
397 switch ( (x+y)%3 )
398 {
399 case 0: *dest++ = (byte) (r >> 2) ; break;
400 case 1: *dest++ = (byte) (0x40 + (g >> 2)); break;
401 case 2: *dest++ = (byte) (0x80 + (b >> 2)); break;
402 }
403 }
404
405 src_data += src_stride;
406 dest_data += dest_stride;
407 }
408 gbm->bpp = 8;
409 }
410/*...e*/
411
412int main(int argc, char *argv[])
413 {
414 BOOLEAN errdiff = FALSE, halftone = FALSE, ok = TRUE;
415 int htmode = 0;
416 char *map = "7x8x4";
417 char *pal = NULL;
418 char fn_src[500+1], fn_dst[500+1], *opt_src, *opt_dst;
419 int fd, ft_src, ft_dst, i, stride, bytes, flag, m, dest_bpp;
420 byte rm, gm, bm;
421 int ncols;
422 GBM_ERR rc;
423 GBMFT gbmft;
424 GBM gbm;
425 GBMRGB gbmrgb[0x100];
426 byte *data;
427
428/*...sprocess command line options:8:*/
429for ( i = 1; i < argc; i++ )
430 {
431 if ( argv[i][0] != '-' )
432 break;
433 else if ( argv[i][1] == '-' )
434 { ++i; break; }
435 switch ( argv[i][1] )
436 {
437 case 'e': errdiff = TRUE;
438 break;
439 case 'h': halftone = TRUE;
440 if ( argv[i][2] != '\0' && isdigit(argv[i][2]) )
441 htmode = argv[i][2] - '0';
442 break;
443 case 'm': if ( ++i == argc )
444 fatal("expected map argument");
445 map = argv[i];
446 break;
447 case 'p': if ( ++i == argc )
448 fatal("expected palette argument");
449 pal = argv[i];
450 break;
451 default: usage();
452 break;
453 }
454 }
455
456if ( errdiff && halftone )
457 fatal("error-diffusion and halftoning can't both be done at once");
458/*...e*/
459/*...sdeduce mapping and bits per pixel etc\46\:8:*/
460if ( get_masks(map, &rm, &gm, &bm) && map[5] == '\0' )
461 {
462 m = CVT_RGB;
463 dest_bpp = 24;
464 }
465else if ( same(map, "freq", 4) )
466 {
467 m = CVT_FREQ;
468 dest_bpp = 8;
469 if ( !get_masks(map+4, &rm, &gm, &bm) )
470 fatal("freqR:G:B:N has bad/missing R:G:B");
471 if ( map[9] != ':' )
472 fatal("freqR:G:B:N has bad/missing :N");
473 sscanf(map+10, "%i", &ncols);
474 if ( ncols < 1 || ncols > 256 )
475 fatal("freqR:G:B:N N number between 1 and 256 required");
476 }
477else if ( same(map, "mcut", 4) )
478 {
479 m = CVT_MCUT;
480 dest_bpp = 8;
481 sscanf(map+4, "%i", &ncols);
482 if ( ncols < 1 || ncols > 256 )
483 fatal("mcutN N number between 1 and 256 required");
484 }
485else
486 {
487 int j;
488
489 for ( j = 0; j < N_MAPINFOS; j++ )
490 if ( same(map, mapinfos[j].name, strlen(map) + 1) )
491 break;
492 if ( j == N_MAPINFOS )
493 fatal("unrecognised mapping %s", map);
494 m = mapinfos[j].m;
495 dest_bpp = mapinfos[j].dest_bpp;
496 }
497/*...e*/
498
499 if ( i == argc )
500 usage();
501 strcpy(fn_src, argv[i++]);
502 strcpy(fn_dst, ( i == argc ) ? fn_src : argv[i++]);
503 if ( i < argc )
504 usage();
505
506 if ( (opt_src = strchr(fn_src, ',')) != NULL )
507 *opt_src++ = '\0';
508 else
509 opt_src = "";
510
511 if ( (opt_dst = strchr(fn_dst, ',')) != NULL )
512 *opt_dst++ = '\0';
513 else
514 opt_dst = "";
515
516 gbm_init();
517
518 if ( gbm_guess_filetype(fn_src, &ft_src) != GBM_ERR_OK )
519 fatal("can't guess bitmap file format for %s", fn_src);
520
521 if ( gbm_guess_filetype(fn_dst, &ft_dst) != GBM_ERR_OK )
522 fatal("can't guess bitmap file format for %s", fn_dst);
523
524 if ( (fd = gbm_io_open(fn_src, O_RDONLY|O_BINARY)) == -1 )
525 fatal("can't open %s", fn_src);
526
527 if ( (rc = gbm_read_header(fn_src, fd, ft_src, &gbm, opt_src)) != GBM_ERR_OK )
528 {
529 gbm_io_close(fd);
530 fatal("can't read header of %s: %s", fn_src, gbm_err(rc));
531 }
532
533 gbm_query_filetype(ft_dst, &gbmft);
534 switch ( dest_bpp )
535 {
536 case 24: flag = GBM_FT_W24; break;
537 case 8: flag = GBM_FT_W8; break;
538 case 4: flag = GBM_FT_W4; break;
539 case 1: flag = GBM_FT_W1; break;
540 }
541
542 if ( (gbmft.flags & flag) == 0 )
543 {
544 gbm_io_close(fd);
545 fatal("output bitmap format %s does not support writing %d bpp data",
546 gbmft.short_name, dest_bpp);
547 }
548
549 if ( (rc = gbm_read_palette(fd, ft_src, &gbm, gbmrgb)) != GBM_ERR_OK )
550 {
551 gbm_io_close(fd);
552 fatal("can't read palette of %s: %s", fn_src, gbm_err(rc));
553 }
554
555 stride = ( ((gbm.w * gbm.bpp + 31)/32) * 4 );
556 bytes = stride * gbm.h;
557 if ( (data = malloc((size_t) bytes)) == NULL )
558 {
559 gbm_io_close(fd);
560 fatal("out of memory allocating %d bytes", bytes);
561 }
562
563 if ( (rc = gbm_read_data(fd, ft_src, &gbm, data)) != GBM_ERR_OK )
564 {
565 free(data);
566 gbm_io_close(fd);
567 fatal("can't read bitmap data of %s: %s", fn_src, gbm_err(rc));
568 }
569
570 gbm_io_close(fd);
571
572 /* Now expand bits per pixel if necessary */
573
574 expand_to_24bit(&gbm, gbmrgb, &data);
575
576 if ( errdiff )
577 m |= CVT_ERRDIFF;
578
579 if ( halftone )
580 m |= CVT_HALFTONE;
581
582 switch ( m )
583 {
584 case CVT_BW:
585 gbm_trunc_pal_BW(gbmrgb);
586 gbm_trunc_BW(&gbm, data, data);
587 break;
588 case CVT_4G:
589 gbm_trunc_pal_4G(gbmrgb);
590 gbm_trunc_4G(&gbm, data, data);
591 break;
592 case CVT_8:
593 gbm_trunc_pal_8(gbmrgb);
594 gbm_trunc_8(&gbm, data, data);
595 break;
596 case CVT_VGA:
597 gbm_trunc_pal_VGA(gbmrgb);
598 gbm_trunc_VGA(&gbm, data, data);
599 break;
600 case CVT_784:
601 gbm_trunc_pal_7R8G4B(gbmrgb);
602 gbm_trunc_7R8G4B(&gbm, data, data);
603 break;
604 case CVT_666:
605 gbm_trunc_pal_6R6G6B(gbmrgb);
606 gbm_trunc_6R6G6B(&gbm, data, data);
607 break;
608 case CVT_8G:
609 to_grey_pal(gbmrgb);
610 to_grey(&gbm, data, data);
611 break;
612 case CVT_TRIPEL:
613 tripel_pal(gbmrgb);
614 tripel(&gbm, data, data);
615 break;
616 case CVT_PAL1BPP:
617 get_pal(pal, gbmrgb, 1, &ncols);
618 gbm_trunc_1bpp(&gbm, data, data, gbmrgb, ncols);
619 break;
620 case CVT_PAL4BPP:
621 get_pal(pal, gbmrgb, 4, &ncols);
622 gbm_trunc_4bpp(&gbm, data, data, gbmrgb, ncols);
623 break;
624 case CVT_PAL8BPP:
625 get_pal(pal, gbmrgb, 8, &ncols);
626 gbm_trunc_8bpp(&gbm, data, data, gbmrgb, ncols);
627 break;
628 case CVT_FREQ:
629 memset(gbmrgb, 0, sizeof(gbmrgb));
630 ok = gbm_hist(&gbm, data, gbmrgb, data, ncols, rm, gm, bm);
631 break;
632 case CVT_RGB:
633 gbm_trunc_24(&gbm, data, data, rm, gm, bm);
634 break;
635 case CVT_MCUT:
636 ok = gbm_mcut(&gbm, data, gbmrgb, data, ncols);
637 break;
638 case CVT_BW | CVT_ERRDIFF:
639 gbm_errdiff_pal_BW(gbmrgb);
640 ok = gbm_errdiff_BW(&gbm, data, data);
641 break;
642 case CVT_4G | CVT_ERRDIFF:
643 gbm_errdiff_pal_4G(gbmrgb);
644 ok = gbm_errdiff_4G(&gbm, data, data);
645 break;
646 case CVT_8 | CVT_ERRDIFF:
647 gbm_errdiff_pal_8(gbmrgb);
648 ok = gbm_errdiff_8(&gbm, data, data);
649 break;
650 case CVT_VGA | CVT_ERRDIFF:
651 gbm_errdiff_pal_VGA(gbmrgb);
652 ok = gbm_errdiff_VGA(&gbm, data, data);
653 break;
654 case CVT_784 | CVT_ERRDIFF:
655 gbm_errdiff_pal_7R8G4B(gbmrgb);
656 ok = gbm_errdiff_7R8G4B(&gbm, data, data);
657 break;
658 case CVT_666 | CVT_ERRDIFF:
659 gbm_errdiff_pal_6R6G6B(gbmrgb);
660 ok = gbm_errdiff_6R6G6B(&gbm, data, data);
661 break;
662 case CVT_RGB | CVT_ERRDIFF:
663 ok = gbm_errdiff_24(&gbm, data, data, rm, gm, bm);
664 break;
665 case CVT_784 | CVT_HALFTONE:
666 gbm_ht_pal_7R8G4B(gbmrgb);
667 gbm_ht_7R8G4B_2x2(&gbm, data, data);
668 break;
669 case CVT_666 | CVT_HALFTONE:
670 gbm_ht_pal_6R6G6B(gbmrgb);
671 gbm_ht_6R6G6B_2x2(&gbm, data, data);
672 break;
673 case CVT_8 | CVT_HALFTONE:
674 gbm_ht_pal_8(gbmrgb);
675 switch ( htmode )
676 {
677 default:
678 case 0: gbm_ht_8_3x3(&gbm, data, data); break;
679 case 1: gbm_ht_8_2x2(&gbm, data, data); break;
680 }
681 break;
682 case CVT_VGA | CVT_HALFTONE:
683 gbm_ht_pal_VGA(gbmrgb);
684 switch ( htmode )
685 {
686 default:
687 case 0: gbm_ht_VGA_3x3(&gbm, data, data); break;
688 case 1: gbm_ht_VGA_2x2(&gbm, data, data); break;
689 }
690 break;
691 case CVT_RGB | CVT_HALFTONE:
692 gbm_ht_24_2x2(&gbm, data, data, rm, gm, bm);
693 break;
694 default:
695 fatal("bad mapping/error-diffusion/halftone combination");
696 }
697
698 if ( !ok )
699 fatal("unable to perform mapping");
700
701 gbm.bpp = dest_bpp;
702
703 if ( (fd = gbm_io_create(fn_dst, O_WRONLY|O_BINARY)) == -1 )
704 fatal("can't create %s", fn_dst);
705
706 if ( (rc = gbm_write(fn_dst, fd, ft_dst, &gbm, gbmrgb, data, opt_dst)) != GBM_ERR_OK )
707 {
708 gbm_io_close(fd);
709 remove(fn_dst);
710 fatal("can't write %s: %s", fn_dst, gbm_err(rc));
711 }
712
713 gbm_io_close(fd);
714
715 free(data);
716
717 gbm_deinit();
718
719 return 0;
720 }
721/*...e*/
Note: See TracBrowser for help on using the repository browser.