1 /*
2  * $Id: xvpic2.c,v 2.9.1.14 1995/04/24 15:34:15 ikeyan Exp $
3  * xvpic2.c - load and save routines for `PIC2' format pictures.
4  *
5  *
6  * Outline
7  * =======
8  * xvpic2.c supports the PIC2 format image file. It is used some
9  * Japanese personal computer users.
10  *
11  * The PIC2 format is designed by A.Yanagisawa. It is an excellent
12  * format except for its encode/decode speed. ;-)
13  *
14  * The features of the PIC2 format:
15  * - Powerful header information (included author, filename, title,
16  *   saver, product number, created date and comment).
17  * - Reversible compression, and very high compression ratio (in many
18  *   cases, a higher compression ratio than the JPEG compression;
19  *   because of its compression method, PIC2 is especially good at
20  *   pictures like cell animation).
21  * - Can handle full-color (24 bits) image.
22  * - Can include multi image blocks into one PIC2 file.
23  * - Have four different block format (P2SS, P2SF, P2BM and
24  *   P2BI). P2SS format uses arithmetic compression for storing
25  *   data. P2SF uses normal run-length compression. P2BM and P2BI is
26  *   raw image format. Select any one according to the situation.
27  *
28  * Explanation of the PIC2 compression:
29 
30  * - In the first place, try to record pixel color, uses color caches
31  *   which keep some recent colors, and formed according to color's
32  *   frequency.  PIC2 has some color cache spaces that are switched by
33  *   upper pixel value of current pixel.  If cache is hit, record
34  *   that.
35  * - Unfortunately, in the case of color cache didn't hit, record the
36  *   difference from the value estimated with the value of upper and
37  *   left pixel of current pixel (similar to PNG's AVG predictor).
38  * - And extract image's color chain if exist, and record that (it
39  *   results in image's outline).
40  * - In all cases, arithmetic compression is used in the final stage
41  *   before writing the file, which in theory produces the ideal
42  *   compression ratio (P2SS).
43  *
44  * Features
45  * ========
46  * - Support 3,6,9,12,15,18,21,24bit PIC2 format (Load/Save).
47  * - Support all image block formats of PIC2 (Load/Save).
48  * - Support multi block PIC2 file (Load/Save).
49  *
50  *
51  * Bugs
52  * ====
53  * - Unsupport 8bit PIC2 image file.
54  *
55  * If you find other bugs (surely exist :-)), send me bug-report.
56  *
57  *
58  * Author
59  * ======
60  * IKEMOTO Masahiro <ikeyan@airlab.cs.ritsumei.ac.jp>
61  */
62 
63 #define PIC2_IGNORE_UNUSED_FUNCTIONS
64 #define NEEDSDIR
65 
66 #include "xv.h"
67 #include <setjmp.h>
68 
69 #ifdef HAVE_PIC2
70 
71 typedef unsigned long pixel;
72 
73 #define pic2_cextoshort(addr) ( \
74     (((short) (((byte *) addr)[0])) <<  8) | \
75     ( (short) (((byte *) addr)[1])) \
76 )
77 #define pic2_cextolong(addr) ( \
78     (((long)  (((byte *) addr)[0])) << 24) | \
79     (((long)  (((byte *) addr)[1])) << 16) | \
80     (((long)  (((byte *) addr)[2])) <<  8) | \
81     ( (long)  (((byte *) addr)[3])) \
82 )
83 #define pic2_shorttocex(addr, n) { \
84     ((byte *) addr)[0] = (((unsigned short) (n) >>  8) & 0xff); \
85     ((byte *) addr)[1] = ( (unsigned short) (n)        & 0xff); \
86 }
87 #define pic2_longtocex(addr, n) { \
88     ((byte *) addr)[0] = (((unsigned long)  (n) >> 24) & 0xff); \
89     ((byte *) addr)[1] = (((unsigned long)  (n) >> 16) & 0xff); \
90     ((byte *) addr)[2] = (((unsigned long)  (n) >>  8) & 0xff); \
91     ((byte *) addr)[3] = ( (unsigned long)  (n)        & 0xff); \
92 }
93 #define pic2_shift_bits(b, n) (((n) > 0) ? ((b) << (n)) : ((b) >> -(n)))
94 
95 #define PIC2_READ_MODE		0
96 #define PIC2_WRITE_MODE		1
97 
98 #define PIC2_ARITH_CACHE	32
99 #define PIC2_ARITH_CONTEXT	128
100 #define PIC2_FAST_CACHE		64
101 
102 #define PIC2_HEADER_SIZE	124
103 #define PIC2_BLOCK_HEADER_SIZE	26
104 
105 struct pic2_header {
106     char magic[4];
107     char name[18];
108     char subtitle[8];
109     char crlf0[2];
110     char title[30];
111     char crlf1[2];
112     char saver[30];
113     char crlf2[2];
114     char eof[1];
115     char reserve0[1];
116     short flag;
117     short no;
118     long time;
119     long size;
120     short depth;
121     short x_aspect;
122     short y_aspect;
123     short x_max;
124     short y_max;
125     long reserve1;
126 };
127 
128 struct pic2_block {
129     char id[4];
130     long size;
131     short flag;
132     short x_wid;
133     short y_wid;
134     short x_offset;
135     short y_offset;
136     long opaque;
137     long reserve;
138 };
139 
140 struct pic2_info {
141     jmp_buf jmp;
142     FILE *fp;
143     struct {
144 	int rest;
145 	byte cur;
146 	int bits;
147 	char zero;
148     }bs;
149     long fsize;
150     struct pic2_header *header;
151     struct pic2_block *block;
152     int n_pal;
153     int pal_bits;
154     byte pal[256][3];
155     char *comment;
156     char mode;
157     long next_pos;
158     long block_pos;
159     short x_max;
160     short y_max;
161     int ynow;
162     byte *buf;
163     pixel *vram_prev;
164     pixel *vram_now;
165     pixel *vram_next;
166     short *flag_now;
167     short *flag_next;
168     short *flag2_now;
169     short *flag2_next;
170     short *flag2_next2;
171     pixel (*cache)[PIC2_ARITH_CACHE];
172     unsigned short *cache_pos;
173     unsigned short *mulu_tab;
174     long aa;
175     long cc;
176     long dd;
177     char cache_hit_c;
178     int (*next_line) PARM((struct pic2_info *, pixel **));
179     char writing_grey;
180     char pagebname[64];
181     int pnum;
182 };
183 
184 static void pic2_open_file             PARM((struct pic2_info*,char*));
185 static void pic2_read_header           PARM((struct pic2_info*));
186 static void pic2_read_block_header1    PARM((struct pic2_info*));
187 static void pic2_read_block_header2    PARM((struct pic2_info*));
188 static short pic2_arith_decode_bit     PARM((struct pic2_info*,int));
189 static short pic2_arith_decode_nn      PARM((struct pic2_info*,int));
190 static void pic2_arith_expand_chain    PARM((struct pic2_info*,int,int,pixel));
191 static short pic2_arith_get_number     PARM((struct pic2_info*,int,int));
192 static pixel pic2_arith_read_color     PARM((struct pic2_info*,int));
193 static int pic2_arith_expand_line      PARM((struct pic2_info*,pixel**));
194 static int pic2_arith_loader_init      PARM((struct pic2_info*));
195 static int pic2_fast_read_length       PARM((struct pic2_info*));
196 static void pic2_fast_expand_chain     PARM((struct pic2_info*,int,pixel));
197 static pixel pic2_fast_read_color      PARM((struct pic2_info*,pixel));
198 static int pic2_fast_expand_line       PARM((struct pic2_info*,pixel**));
199 static int pic2_fast_loader_init       PARM((struct pic2_info*));
200 static int pic2_beta_expand_line       PARM((struct pic2_info*,pixel**));
201 static int pic2_beta_loader_init       PARM((struct pic2_info*));
202 static void pic2_make_xvpic            PARM((struct pic2_info*,byte**,
203 					     byte*,byte*,byte*));
204 static void pic2_make_pagefile         PARM((struct pic2_info*,char*,int));
205 static void pic2_setup_pic2_info       PARM((struct pic2_info*,
206 					     char*,char*,char*,char*,
207 					     int,int,int,int,int,int,char *));
208 static void pic2_append                PARM((struct pic2_info*));
209 static void pic2_write_header1         PARM((struct pic2_info*));
210 static void pic2_write_header2         PARM((struct pic2_info*));
211 static void pic2_write_block_header    PARM((struct pic2_info*));
212 static void pic2_arith_write_zero_bit  PARM((struct pic2_info*));
213 static void pic2_arith_flush_bit_buf   PARM((struct pic2_info*));
214 static void pic2_arith_carry_bit       PARM((struct pic2_info*));
215 static void pic2_arith_encode_bit      PARM((struct pic2_info*,int,int));
216 static void pic2_arith_encode_nbyte    PARM((struct pic2_info*,int,int,int));
217 static void pic2_arith_encode_nn       PARM((struct pic2_info*,int,int));
218 static void pic2_arith_press_chain     PARM((struct pic2_info*,int));
219 static void pic2_arith_put_number      PARM((struct pic2_info*,int,int,int));
220 static void pic2_arith_write_color     PARM((struct pic2_info*,int));
221 static void pic2_arith_press_line2     PARM((struct pic2_info*));
222 static int pic2_arith_press_line       PARM((struct pic2_info*,pixel**));
223 static int pic2_arith_saver_init       PARM((struct pic2_info*,pixel**));
224 static void pic2_fast_write_length     PARM((struct pic2_info*,int));
225 static void pic2_fast_press_chain      PARM((struct pic2_info*,int));
226 static void pic2_fast_press_chain2     PARM((struct pic2_info*,int));
227 static void pic2_fast_flush_chain      PARM((struct pic2_info*));
228 static void pic2_fast_write_color      PARM((struct pic2_info*,int));
229 static void pic2_fast_press_line2      PARM((struct pic2_info*));
230 static int pic2_fast_press_line        PARM((struct pic2_info*,pixel**));
231 static int pic2_fast_saver_init        PARM((struct pic2_info*,pixel**));
232 static int pic2_beta_press_line        PARM((struct pic2_info*,pixel**));
233 static int pic2_beta_saver_init        PARM((struct pic2_info*,pixel**));
234 static void pic2_write_data            PARM((struct pic2_info*,byte*,
235 					     int,int,int,int,int,
236 					     byte*,byte*,byte*,int,int));
237 static int pic2_next_line              PARM((struct pic2_info*,pixel**));
238 static int pic2_next_block             PARM((struct pic2_info*));
239 static int pic2_find_block             PARM((struct pic2_info*));
240 static int pic2_load_block             PARM((struct pic2_info*));
241 static int pic2_save_block             PARM((struct pic2_info*,pixel**,
242 					     int,int,int,int,char*,pixel));
243 #ifndef PIC2_IGNORE_UNUSED_FUNCTIONS
244 static void pic2_read_palette          PARM((struct pic2_info*,
245 					     byte*,byte*,byte*));
246 static void pic2_write_palette         PARM((struct pic2_info*,int,int,
247 					     byte*,byte*,byte*));
248 #endif /* !PIC2_IGNORE_UNUSED_FUNCTIONS */
249 static byte pic2_convert_color_bits    PARM((int,int,int));
250 static byte pic2_pad_color_bits        PARM((int,int,int));
251 static byte pic2_reduce_color_bits     PARM((int,int,int));
252 static pixel pic2_exchange_rg          PARM((pixel,int));
253 static void pic2_handle_para           PARM((struct pic2_info*,int));
254 static int pic2_alloc_buffer           PARM((struct pic2_info*));
255 static void pic2_free_buffer           PARM((struct pic2_info*));
256 static long pic2_seek_file             PARM((struct pic2_info*,long,int));
257 static long pic2_tell_file             PARM((struct pic2_info*));
258 static int pic2_read_file              PARM((struct pic2_info*,void*,size_t));
259 static long pic2_read_long             PARM((struct pic2_info*));
260 static short pic2_read_short           PARM((struct pic2_info*));
261 static char pic2_read_char             PARM((struct pic2_info*));
262 static int pic2_write_file             PARM((struct pic2_info*,void*,size_t));
263 static int pic2_write_long             PARM((struct pic2_info*,long));
264 static int pic2_write_short            PARM((struct pic2_info*,int));
265 static int pic2_write_char             PARM((struct pic2_info*,int));
266 static unsigned long pic2_read_bits    PARM((struct pic2_info*,int));
267 static void pic2_write_bits            PARM((struct pic2_info*,
268 					     unsigned long,int));
269 static void pic2_flush_bits            PARM((struct pic2_info*));
270 static void pic2_memory_error          PARM((char*,char*));
271 static void pic2_error                 PARM((struct pic2_info*,int));
272 static void pic2_file_error            PARM((struct pic2_info*,int));
273 static void pic2_init_info             PARM((struct pic2_info*));
274 static void pic2_cleanup_pic2_info     PARM((struct pic2_info*,int));
275 static void pic2_cleanup_pinfo         PARM((PICINFO*));
276 static void pic2_show_pic2_info        PARM((struct pic2_info*));
277 static char *pic2_strncpy              PARM((char*,char*,size_t));
278 static void *pic2_malloc               PARM((size_t,char*));
279 static void *pic2_new                  PARM((size_t,char*));
280 
281 static int WritePIC2                   PARM((FILE*,byte*,int,int,int,
282 					     byte*,byte*,byte*,int,int,char*,
283 					     int,int,int,int,int,char*));
284 
285 static char *pic2_id = "P2DT";
286 
287 /* Error Messages */
288 static char *pic2_msgs[] = {
289     NULL,
290 #define PIC2_OPEN 1
291     "can't open file.",
292 #define PIC2_CORRUPT 2
293     "file corrupted.",
294 #define PIC2_FORMAT 3
295     "not PIC2 format.",
296 #define PIC2_DEPTH 4
297     "bit depths not divisible by 3 are unsupported.",
298 #define PIC2_TMPFILE 5
299     "unable to create temporary filename???",
300 #define PIC2_PAGE 6
301     "couldn't load the page.",
302 #define PIC2_APPEND 7
303     "cannot append.",
304 #define PIC2_WRITE 8
305     "write failed.",
306 };
307 
308 struct _form_tab {
309     char *id;
310     int (*loader_init) PARM((struct pic2_info *));
311     int (*saver_init) PARM((struct pic2_info *, pixel **));
312 } form_tab[] = {
313 	{ "P2SS", pic2_arith_loader_init, pic2_arith_saver_init},
314 	{ "P2SF", pic2_fast_loader_init, pic2_fast_saver_init},
315 	{ "P2BM", pic2_beta_loader_init, pic2_beta_saver_init},
316 	{ "P2BI", pic2_beta_loader_init, pic2_beta_saver_init},
317 };
318 #define	n_form_tab (sizeof(form_tab) / sizeof(struct _form_tab))
319 #define P2SS 0
320 #define P2SF 1
321 #define P2BM 2
322 #define P2BI 3
323 
324 /* The main routine to load a PIC2 file. */
LoadPIC2(fname,pinfo,quick)325 int LoadPIC2(fname, pinfo, quick)
326 char *fname;
327 PICINFO *pinfo;
328 int quick;
329 {
330     int e, i, block;
331     struct pic2_info pic2;
332 
333     if (DEBUG)
334 	fputs("LoadPIC2:\n", stderr);
335 
336     pic2_init_info(&pic2);
337 
338     if ((e = setjmp(pic2.jmp)) != 0){
339 	/* When an error occurs, comes here. */
340 	pic2_free_buffer(&pic2);
341 	pic2_cleanup_pic2_info(&pic2, 0);
342 	pic2_cleanup_pinfo(pinfo);
343 	if (pic2split)
344 	    KillPageFiles(pic2.pagebname, pic2.pnum);
345 	SetCursors(-1);
346 	if (DEBUG)
347 	    fputs("\n", stderr);
348 	return (0);
349     }
350     pic2_open_file(&pic2, fname);
351     pic2_read_header(&pic2);
352 
353     if ((i = pic2_find_block(&pic2)) == 0)
354 	pic2_file_error(&pic2, PIC2_CORRUPT);
355 
356     block = 1;
357     while(i == 2) {
358 	SetISTR(ISTR_WARNING, "unknown or invalid block #%d.", block);
359 	i = pic2_next_block(&pic2);
360 	block++;
361     }
362 
363     if (pic2split && !quick) {
364 	char firstpage[512];
365 	struct stat st;
366 #ifndef USE_MKSTEMP
367 	int tmpfd;
368 #endif
369 
370 #ifndef VMS
371 	sprintf(pic2.pagebname, "%s/xvpic2XXXXXX", tmpdir);
372 #else
373 	sprintf(pic2.pagebname, "Sys$Scratch:xvpic2XXXXXX");
374 #endif
375 #ifdef USE_MKSTEMP
376 	close(mkstemp(pic2.pagebname));
377 #else
378 	mktemp(pic2.pagebname);
379 	tmpfd = open(pic2.pagebname, O_WRONLY|O_CREAT|O_EXCL, S_IRWUSR);
380 	if (tmpfd < 0) FatalError("LoadPIC2(): can't create temporary file");
381 	close(tmpfd);
382 #endif
383 	if (pic2.pagebname[0] == '\0')
384 	    pic2_error(&pic2, PIC2_TMPFILE);
385 	strcat(pic2.pagebname, ".");
386 
387 	sprintf(firstpage, "%s%d", pic2.pagebname, 1);
388 	if (stat(firstpage, &st)) {
389 	    for (pic2.pnum = 1; i >= 1; pic2.pnum++) {
390 		pic2_load_block(&pic2);
391 		pic2_make_pagefile(&pic2, pic2.pagebname, pic2.pnum);
392 		while(block++, (i = pic2_next_block(&pic2)) == 2)
393 		    SetISTR(ISTR_WARNING,
394 			    "unknown or invalid block #%d.", block);
395 	    }
396             pinfo->numpages = --pic2.pnum;
397             if (!LoadPIC2(firstpage, pinfo, 1))
398 		pic2_error(&pic2, PIC2_PAGE);
399 	    if (pic2.pnum == 1)
400 		unlink(firstpage);
401 	    else
402 		strcpy(pinfo->pagebname, pic2.pagebname);
403 	} else
404             if (!LoadPIC2(fname, pinfo, 1))
405 		pic2_error(&pic2, PIC2_PAGE);
406     } else {
407 	char buf[128], format[64];
408 	int j;
409 
410 	pinfo->w = pic2.x_max;
411 	pinfo->h = pic2.y_max;
412 	pinfo->normw = pinfo->w;
413 	pinfo->normh = pinfo->h;
414 	pinfo->type = PIC24;
415 	for (j = 0; j < n_form_tab; j++) {
416 	    if (xvbcmp(pic2.block->id, form_tab[j].id, (size_t) 4) == 0)
417 		break;
418 	}
419 	pinfo->frmType = F_PIC2;
420 	pinfo->colType = F_FULLCOLOR;
421 	pinfo->comment = pic2.comment;
422 
423 	if (pic2split) {
424 	    pic2_make_xvpic(&pic2, &pinfo->pic, pinfo->r, pinfo->g, pinfo->b);
425 	    strcpy(format, form_tab[j].id);
426 	} else {
427 	    for (pic2.pnum = 1; i >= 1; pic2.pnum++) {
428 		SetISTR(ISTR_INFO, "composing block #%d", block);
429 		pic2_make_xvpic(&pic2, &pinfo->pic,
430 				pinfo->r, pinfo->g, pinfo->b);
431 		while(block++, (i = pic2_next_block(&pic2)) == 2)
432 		    SetISTR(ISTR_WARNING,
433 			    "unknown or invalid block #%d.", block);
434 	    }
435 	    if (--block > 1)
436 		if (block != --pic2.pnum)
437 		    sprintf(format, "MultiBlock[%d/%d]", block, pic2.pnum);
438 		else
439 		    sprintf(format, "MultiBlock[%d]", block);
440 	    else
441 		strcpy(format, form_tab[j].id);
442 	}
443 	sprintf(buf, "PIC2(%s). %d colors (%ld bytes)", format,
444 		(int) 1 << pic2.header->depth, pic2.fsize);
445 	strcat(pinfo->fullInfo, buf);
446 	sprintf(pinfo->shrtInfo, "%dx%d(aspect %4.2f) PIC2(%s).",
447 		pinfo->w, pinfo->h,
448 		(float) pic2.header->x_aspect / (float) pic2.header->y_aspect,
449 		format);
450 	if (!nopicadjust)
451 	    normaspect = (float) pic2.header->x_aspect
452 			 / (float) pic2.header->y_aspect;
453     }
454     pic2_cleanup_pic2_info(&pic2, 0);
455     SetCursors(-1);
456     if (DEBUG)
457 	fputs("\n", stderr);
458     return (1);
459 }
460 
461 /*
462  * This function opens the file, and set its size.
463  */
pic2_open_file(pi,fname)464 static void pic2_open_file(pi, fname)
465     struct pic2_info *pi;
466     char *fname;
467 {
468     if ((pi->fp = fopen(fname, "rb")) == NULL)
469 	pic2_file_error(pi, PIC2_OPEN);
470     fseek(pi->fp, (size_t) 0, SEEK_END);
471     pi->fsize = ftell(pi->fp);
472     fseek(pi->fp, (size_t) 0, SEEK_SET);
473 }
474 
475 /*
476  * These functions read the PIC2 header informations.
477  * pic2_read_header:
478  *	reads the PIC2 header.
479  * pic2_read_block_header1:
480  *	reads the id number of block header and the size of block.
481  * pic2_read_block_header2:
482  *	reads the rest of block header.
483  */
pic2_read_header(pi)484 static void pic2_read_header(pi)
485 struct pic2_info *pi;
486 {
487     long s_comment;
488 
489     pi->mode = PIC2_READ_MODE;
490 
491     /* read header image */
492     pic2_read_file(pi, pi->header->magic, 4);
493     pic2_read_file(pi, pi->header->name, 18);
494     pic2_read_file(pi, pi->header->subtitle, 8);
495     pic2_read_file(pi, pi->header->crlf0, 2);
496     pic2_read_file(pi, pi->header->title, 30);
497     pic2_read_file(pi, pi->header->crlf1, 2);
498     pic2_read_file(pi, pi->header->saver, 30);
499     pic2_read_file(pi, pi->header->crlf2, 2);
500     pic2_read_file(pi, pi->header->eof, 1);
501     pic2_read_file(pi, pi->header->reserve0, 1);
502     pi->header->flag = pic2_read_short(pi);
503     pi->header->no = pic2_read_short(pi);
504     pi->header->time = pic2_read_long(pi);
505     pi->header->size = pic2_read_long(pi);
506     pi->header->depth = pic2_read_short(pi);
507     pi->header->x_aspect = pic2_read_short(pi);
508     pi->header->y_aspect = pic2_read_short(pi);
509     pi->header->x_max = pic2_read_short(pi);
510     pi->header->y_max = pic2_read_short(pi);
511     pi->header->reserve1 = pic2_read_long(pi);
512 
513     /* check magic number */
514     if (strncmp(pi->header->magic, pic2_id, (size_t) 4) != 0)
515         pic2_error(pi, PIC2_FORMAT);
516 
517     /* read palette data, if exists */
518     if (pi->header->flag & 1) {
519 	pi->pal_bits = pic2_read_char(pi);
520 	pi->n_pal = pic2_read_short(pi);
521 	pic2_read_file(pi, pi->pal, (size_t) (pi->n_pal * 3));
522     }
523 
524     /* read comments */
525     s_comment = pi->header->size - pic2_tell_file(pi);
526     pi->comment = pic2_new(s_comment + 1, "pic2_read_header");
527     pic2_read_file(pi, pi->comment, (size_t) s_comment);
528     pi->comment[s_comment] = '\0';
529 
530     pi->x_max = pi->header->x_max;
531     pi->y_max = pi->header->y_max;
532 
533     /* set initial block point */
534     pi->next_pos = pic2_tell_file(pi);
535 }
536 
pic2_read_block_header1(pi)537 static void pic2_read_block_header1(pi)
538 struct pic2_info *pi;
539 {
540     pic2_read_file(pi, pi->block->id, 4);
541     pi->block->size = pic2_read_long(pi);
542 }
543 
pic2_read_block_header2(pi)544 static void pic2_read_block_header2(pi)
545 struct pic2_info *pi;
546 {
547     pi->block->flag = pic2_read_short(pi);
548     pi->block->x_wid = pic2_read_short(pi);
549     pi->block->y_wid = pic2_read_short(pi);
550     pi->block->x_offset = pic2_read_short(pi);
551     pi->block->y_offset = pic2_read_short(pi);
552     pi->block->opaque = pic2_read_long(pi);
553     pi->block->reserve = pic2_read_long(pi);
554 }
555 
556 /*
557  * These functions are arithmetic pic2 format extractor.
558  */
pic2_arith_decode_bit(pi,c)559 static short pic2_arith_decode_bit(pi, c)
560 struct pic2_info *pi;
561 int c;
562 {
563     unsigned short pp;
564 
565     pp = pi->mulu_tab[(pi->aa & 0x7f00) / 2 + c];
566     if (pi->dd >= (int) pp) {
567 	pi->dd -= pp;
568 	pi->aa -= pp;
569 
570 	while ((short) pi->aa >= 0) {
571 	    pi->dd *= 2;
572 	    if (pic2_read_bits(pi, 1))
573 		pi->dd++;
574 	    pi->aa *= 2;
575 	}
576 	return (1);
577     } else {
578 	pi->aa = pp;
579 
580 	while ((short) pi->aa >= 0) {
581 	    pi->dd *= 2;
582 	    if (pic2_read_bits(pi, 1))
583 		pi->dd++;
584 	    pi->aa *= 2;
585 	}
586 	return (0);
587     }
588 }
589 
pic2_arith_decode_nn(pi,c)590 static short pic2_arith_decode_nn(pi, c)
591 struct pic2_info *pi;
592 int c;
593 {
594     int n;
595 
596     if (pic2_arith_decode_bit(pi, c)) {
597 	/* n < 1 */
598 	n = 0;
599     } else if (pic2_arith_decode_bit(pi, c + 1)) {
600 	/* n < 1 + 2 */
601 	n = 1;
602 	if (pic2_arith_decode_bit(pi, c + 8))
603 	    n += 1;
604     } else if (pic2_arith_decode_bit(pi, c + 2)) {
605 	/* n < 1 + 2 + 4 */
606 	n = 1 + 2;
607 	if (pic2_arith_decode_bit(pi,  c + 8))
608 	    n += 1;
609 	if (pic2_arith_decode_bit(pi,  c + 9))
610 	    n += 2;
611     } else if (pic2_arith_decode_bit(pi, c + 3)) {
612 	/* n < 1 + 2 + 4 + 8 */
613 	n = 1 + 2 + 4;
614 	if (pic2_arith_decode_bit(pi, c + 8))
615 	    n += 1;
616 	if (pic2_arith_decode_bit(pi, c + 9))
617 	    n += 2;
618 	if (pic2_arith_decode_bit(pi, c + 10))
619 	    n += 4;
620     } else if (pic2_arith_decode_bit(pi, c + 4)) {
621 	/* n < 1 + 2 + 4 + 8 + 16 */
622 	n = 1 + 2 + 4 + 8;
623 	if (pic2_arith_decode_bit(pi, c + 8))
624 	    n += 1;
625 	if (pic2_arith_decode_bit(pi, c + 9))
626 	    n += 2;
627 	if (pic2_arith_decode_bit(pi, c + 10))
628 	    n += 4;
629 	if (pic2_arith_decode_bit(pi, c + 11))
630 	    n += 8;
631     } else if (pic2_arith_decode_bit(pi,  c + 5)) {
632 	/* n < 1 + 2 + 4 + 8 + 16 + 32 */
633 	n = 1 + 2 + 4 + 8 + 16;
634 	if (pic2_arith_decode_bit(pi, c + 8))
635 	    n += 1;
636 	if (pic2_arith_decode_bit(pi, c + 9))
637 	    n += 2;
638 	if (pic2_arith_decode_bit(pi, c + 10))
639 	    n += 4;
640 	if (pic2_arith_decode_bit(pi, c + 11))
641 	    n += 8;
642 	if (pic2_arith_decode_bit(pi, c + 12))
643 	    n += 16;
644 
645     } else if (pic2_arith_decode_bit(pi, c + 6)) {
646 	/* n < 1 + 2 + 4 + 8 + 16 + 32 + 64 */
647 	n = 1 + 2 + 4 + 8 + 16 + 32;
648 	if (pic2_arith_decode_bit(pi, c + 8))
649 	    n += 1;
650 	if (pic2_arith_decode_bit(pi, c + 9))
651 	    n += 2;
652 	if (pic2_arith_decode_bit(pi, c + 10))
653 	    n += 4;
654 	if (pic2_arith_decode_bit(pi, c + 11))
655 	    n += 8;
656 	if (pic2_arith_decode_bit(pi, c + 12))
657 	    n += 16;
658 	if (pic2_arith_decode_bit(pi, c + 13))
659 	    n += 32;
660 
661     } else if (pic2_arith_decode_bit(pi, c + 7)) {
662 	/* n < 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 */
663 	n = 1 + 2 + 4 + 8 + 16 + 32 + 64;
664 	if (pic2_arith_decode_bit(pi, c + 8))
665 	    n += 1;
666 	if (pic2_arith_decode_bit(pi, c + 9))
667 	    n += 2;
668 	if (pic2_arith_decode_bit(pi, c + 10))
669 	    n += 4;
670 	if (pic2_arith_decode_bit(pi, c + 11))
671 	    n += 8;
672 	if (pic2_arith_decode_bit(pi, c + 12))
673 	    n += 16;
674 	if (pic2_arith_decode_bit(pi, c + 13))
675 	    n += 32;
676 	if (pic2_arith_decode_bit(pi, c + 14))
677 	    n += 64;
678 
679     } else {
680 	n = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128;
681     }
682     return (n);
683 }
684 
pic2_arith_expand_chain(pi,x,y,cc)685 static void pic2_arith_expand_chain(pi, x, y, cc)
686 struct pic2_info *pi;
687 int x, y;
688 pixel cc;
689 {
690     static const unsigned short c_tab[] = {
691 	80 + 6 * 5,	/* -5 */
692 	80 + 6 * 4,
693 	80 + 6 * 3,
694 	80 + 6 * 2,
695 	80 + 6 * 1,
696 	80 + 6 * 0,	/* 0  */
697 	80 + 6 * 0,	/* 1  */
698     };
699     unsigned short b;
700 
701     b = c_tab[pi->flag_now[x] + 5];
702     if (!pic2_arith_decode_bit(pi, b++)) {
703 	if (pic2_arith_decode_bit(pi, b++))      {	/* down */
704 	    pi->vram_next[x    ] = cc;
705 	    pi->flag_next[x    ] = -1;
706 	} else if (pic2_arith_decode_bit(pi, b++)) {	/* left */
707 	    pi->vram_next[x - 1] = cc;
708 	    pi->flag_next[x - 1] = -2;
709 	} else if (pic2_arith_decode_bit(pi, b++)) {	/* right */
710 	    pi->vram_next[x + 1] = cc;
711 	    pi->flag_next[x + 1] = -3;
712 	} else if (pic2_arith_decode_bit(pi, b++)) {	/* left2 */
713 	    pi->vram_next[x - 2] = cc;
714 	    pi->flag_next[x - 2] = -4;
715 	} else {					/* right2 */
716 	    pi->vram_next[x + 2] = cc;
717 	    pi->flag_next[x + 2] = -5;
718 	}
719     }
720 }
721 
pic2_arith_get_number(pi,c,bef)722 static short pic2_arith_get_number(pi, c, bef)
723 struct pic2_info *pi;
724 int c, bef;
725 {
726     unsigned short n;
727     byte maxcol;
728 
729     maxcol = 0xff >> (8 - pi->header->depth / 3);
730 
731     n = pic2_arith_decode_nn(pi, c);
732     if (bef > ((int) maxcol >> 1)) {
733 	if (n > ((int) maxcol - bef) * 2)
734 	    n = maxcol - n;
735 	else if (n & 1)
736 	    n = n / 2 + bef + 1;
737 	else
738 	    n = bef - n / 2;
739     } else {
740 	if ((int) n > (bef * 2))
741 	    n = n;
742 	else if (n & 1)
743 	    n = n / 2 + bef + 1;
744 	else
745 	    n = bef - n / 2;
746     }
747     return (n);
748 }
749 
pic2_arith_read_color(pi,x)750 static pixel pic2_arith_read_color(pi, x)
751 struct pic2_info *pi;
752 int x;
753 {
754     pixel c1, c2, cc;
755     unsigned short i, j, k, m;
756     short r, g, b, r0, g0, b0;
757     short colbits;
758     pixel rmask, gmask, bmask;
759     byte maxcol;
760 
761     colbits = pi->header->depth / 3;
762     rmask = (0xff >> (8 - colbits)) << (colbits * 2);
763     gmask = (0xff >> (8 - colbits)) <<  colbits;
764     bmask = (0xff >> (8 - colbits));
765     maxcol = (byte) bmask;
766 
767     c1 = pi->vram_prev[x];
768     k = ((c1 >> ((colbits - 3) * 3)) & 0x1c0)
769       | ((c1 >> ((colbits - 3) * 2)) & 0x038)
770       | ((c1 >>  (colbits - 3)     ) & 0x007);
771     if (colbits == 5)
772 	k = pic2_exchange_rg(k, 3);
773 
774     if (pic2_arith_decode_bit(pi, pi->cache_hit_c)) {	/* ouch */
775 	pi->cache_hit_c = 16;
776 
777         c2 = pi->vram_now[x - 1];
778 	r = ((c1 & rmask) + (c2 & rmask)) >> (colbits * 2 + 1);
779 	g = ((c1 & gmask) + (c2 & gmask)) >> (colbits     + 1);
780 	b = ((c1 & bmask) + (c2 & bmask)) >> (              1);
781 
782 	g0 = pic2_arith_get_number(pi, 32, g);
783         r = r + g0 - g;
784 	if (r > (short) maxcol)
785 	    r = maxcol;
786 	else if (r < 0)
787 	    r = 0;
788 
789         b = b + g0 - g;
790 	if (b > (short) maxcol)
791 	    b = maxcol;
792 	else if (b < 0)
793 	    b = 0;
794 
795 	r0 = pic2_arith_get_number(pi, 48, r);
796 	b0 = pic2_arith_get_number(pi, 64, b);
797 
798 	pi->cache_pos[k] = j = (pi->cache_pos[k] - 1) & (PIC2_ARITH_CACHE - 1);
799 	pi->cache[k][j] = cc = (r0 << (colbits * 2)) | (g0 << colbits) | b0;
800     } else {
801 	pi->cache_hit_c = 15;
802 
803 	j = pic2_arith_decode_nn(pi, 17);
804 	m = pi->cache_pos[k];
805 	i = (m + j / 2) & (PIC2_ARITH_CACHE - 1);
806 	j = (m + j) & (PIC2_ARITH_CACHE - 1);
807 
808 	cc = pi->cache[k][j];
809 	pi->cache[k][j] = pi->cache[k][i];
810 	pi->cache[k][i] = pi->cache[k][m];
811 	pi->cache[k][m] = cc;
812     }
813     return (cc);
814 }
815 
pic2_arith_expand_line(pi,line)816 static int pic2_arith_expand_line(pi, line)
817 struct pic2_info *pi;
818 pixel **line;
819 {
820     int ymax;
821     int x, xw;
822     pixel cc;
823 
824     pic2_handle_para(pi, 0);
825 
826     xw = pi->block->x_wid;
827     ymax = pi->block->y_wid - 1;
828 
829     if (pi->ynow > ymax)
830 	return (-2);					/* end */
831 
832     /* set right end of previous line before left end of current line. */
833     if (pi->ynow == 0) {
834 	cc = 0;
835     } else
836 	cc = pi->vram_prev[xw - 1];
837     pi->vram_now[-1] = cc;
838 
839     /* clear flag for change point */
840     xvbzero((char *) pi->flag_next, xw * sizeof(pi->flag_next[0]));
841 
842     /* clear flag for position probability space */
843     xvbzero((char *) pi->flag2_next2, xw * sizeof(pi->flag2_next2[0]));
844 
845     for (x = 0; x < xw; x++) {
846 	if (pi->flag_now[x] < 0) {
847 	    cc = pi->vram_now[x];
848 	    if (pi->ynow < ymax)
849 		pic2_arith_expand_chain(pi, x, pi->ynow, cc);
850 	} else if (pic2_arith_decode_bit(pi, pi->flag2_now[x])) {
851 	    /* ajust probability space around of change point */
852 	    pi->flag2_now  [x + 1]++;
853 	    pi->flag2_now  [x + 2]++;
854 	    pi->flag2_next [x - 1]++;
855 	    pi->flag2_next [x    ]++;
856 	    pi->flag2_next [x + 1]++;
857 	    pi->flag2_next2[x - 1]++;
858 	    pi->flag2_next2[x    ]++;
859 	    pi->flag2_next2[x + 1]++;
860 
861 	    pi->vram_now[x] = cc = pic2_arith_read_color(pi, x);
862 	    if (pi->ynow < ymax)
863 		pic2_arith_expand_chain(pi, x, pi->ynow, cc);
864 	} else
865 	    pi->vram_now[x] = cc;
866     }
867     if (line != NULL)
868 	*line = pi->vram_now;
869     pi->ynow++;
870 
871     pic2_handle_para(pi, 1);
872 
873     return (pi->ynow - 1);
874 }
875 
pic2_arith_loader_init(pi)876 static int pic2_arith_loader_init(pi)
877 struct pic2_info *pi;
878 {
879     unsigned short p2b[256];
880     int i, xw;
881 
882     pi->ynow = 0;
883 
884     /* check the color depth */
885     if (pi->header->depth % 3)
886 	pic2_error(pi, PIC2_DEPTH);
887 
888     /* set function for extract next line */
889     pi->next_line = pic2_arith_expand_line;
890 
891     /* clear cache and flags */
892     xw = pi->block->x_wid;
893     xvbzero((char *) pi->cache, 8 * 8 * 8 * sizeof(pi->cache[0]));
894     xvbzero((char *) pi->cache_pos, 8 * 8 * 8 * sizeof(pi->cache_pos[0]));
895 
896     xvbzero((char *) pi->flag_now, xw * sizeof(pi->flag_now[0]));
897     xvbzero((char *) pi->flag2_now, 8 + xw * sizeof(pi->flag2_now[0]));
898     xvbzero((char *) pi->flag2_next, 8 + xw * sizeof(pi->flag2_next[0]));
899 
900     /* go to picture data field */
901     pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET);
902 
903     /* clear bit field marker */
904     pi->bs.rest = 0;
905     pi->bs.cur = 0;
906 
907     /* read probability table */
908     for (i = 0; i < PIC2_ARITH_CONTEXT; i++)
909 	p2b[i] = pic2_read_short(pi);
910 
911     /* make multiplication table */
912     for (i = 0; i < 16384; i++) {
913 	pi->mulu_tab[i] = (long) (i / 128 + 128) * (int) p2b[i & 127] / 256;
914 	if (pi->mulu_tab[i] == 0) pi->mulu_tab[i] = 1;
915     }
916     /* initialize some valuables */
917     pi->aa = 0xffff;
918     pi->dd = 0;
919     for (i = 0; i < 16; i++) {
920 	pi->dd *= 2;
921 	if (pic2_read_bits(pi, 1))
922 	    pi->dd |= 1;
923     }
924     pi->cache_hit_c = 16;
925 
926     return (0);
927 }
928 
929 /*
930  * These functions are fast pic2 compression extractor.
931  */
pic2_fast_read_length(pi)932 static int pic2_fast_read_length(pi)
933 struct pic2_info *pi;
934 {
935     int a;
936 
937     a = 0;
938     while (pic2_read_bits(pi, 1)) {
939 	a++;
940     }
941     if (a == 0)
942 	return (0);
943     return (pic2_read_bits(pi, a) + (1 << a) - 1);
944 }
945 
pic2_fast_expand_chain(pi,x,cc)946 static void pic2_fast_expand_chain(pi, x, cc)
947 struct pic2_info *pi;
948 int x;
949 pixel cc;
950 {
951     if (pic2_read_bits(pi, 1) != 0) {
952 	if (pic2_read_bits(pi, 1) != 0) {		/* down */
953 	    pi->vram_next[x] = cc;
954 	    pi->flag_next[x] = -1;
955 	} else if (pic2_read_bits(pi, 1) != 0) {
956 	    if (pic2_read_bits(pi, 1) == 0) {		/* left2down */
957 		pi->vram_next[x - 2] = cc;
958 		pi->flag_next[x - 2] = -1;
959 	    } else {					/* left1down */
960 		pi->vram_next[x - 1] = cc;
961 		pi->flag_next[x - 1] = -1;
962 	    }
963 	} else {
964 	    if (pic2_read_bits(pi, 1) == 0) {		/* right2down */
965 		pi->vram_next[x + 2] = cc;
966 		pi->flag_next[x + 2] = -1;
967 	    } else {					/* left1down */
968 		pi->vram_next[x + 1] = cc;
969 		pi->flag_next[x + 1] = -1;
970 	    }
971 	}
972     }
973 }
974 
pic2_fast_read_color(pi,bc)975 static pixel pic2_fast_read_color(pi, bc)
976 struct pic2_info *pi;
977 pixel bc;
978 {
979     pixel cc;
980     unsigned short j, k, m;
981     short depth, colbits;
982     pixel (*cache)[PIC2_FAST_CACHE];
983 
984     depth = pi->header->depth;
985     colbits = depth / 3;
986     cache = (pixel (*)[PIC2_FAST_CACHE]) pi->cache;
987 
988     bc = pic2_exchange_rg(bc, colbits);
989     k = pic2_shift_bits(bc, 8 - depth);
990     if (pic2_read_bits(pi, 1) == 0) {
991 	pi->cache_pos[k] = m = (pi->cache_pos[k] - 1) & (PIC2_FAST_CACHE - 1);
992 	cc = pic2_read_bits(pi, depth);
993 	cc = pic2_exchange_rg(cc, colbits);
994 	cache[k][m] = cc;
995     } else {
996 	j = pic2_read_bits(pi, 6);		/* 6= log2(PIC2_FAST_CACHE) */
997 	m = pi->cache_pos[k];
998 	cc = cache[k][(m + j) & (PIC2_FAST_CACHE - 1)];
999     }
1000     return (cc);
1001 }
1002 
pic2_fast_expand_line(pi,line)1003 static int pic2_fast_expand_line(pi, line)
1004 struct pic2_info *pi;
1005 pixel **line;
1006 {
1007     int ymax;
1008     int x, xw;
1009     pixel cc;
1010 
1011     pic2_handle_para(pi, 0);
1012 
1013     xw = pi->block->x_wid;
1014     ymax = pi->block->y_wid - 1;
1015 
1016     if (pi->ynow > ymax)
1017 	return (-2);
1018 
1019     if (pi->ynow == 0) {
1020 	pi->dd = 0;
1021 	pi->aa = pic2_fast_read_length(pi);
1022 	if (pi->aa == 1023)
1023 	    pi->dd = 1023;
1024 	else if (pi->aa > 1023)
1025 	    pi->aa--;
1026 	cc = 0;
1027     } else
1028 	cc = pi->vram_prev[xw - 1];
1029 
1030     xvbzero((char *) pi->flag_next, xw * sizeof(pi->flag_next[0]));
1031 
1032     for (x = 0; x < xw; x++) {
1033 	if (pi->dd > 0) {
1034 	    if (pi->flag_now[x] < 0) {			/* on chain ? */
1035 		cc = pi->vram_now[x];
1036 		pic2_fast_expand_chain(pi, x, cc);
1037 		if (--pi->dd == 0) {
1038 		    pi->aa = pic2_fast_read_length(pi);
1039 		    if (pi->aa == 1023)
1040 			pi->dd = 1023;
1041 		    else if (pi->aa > 1023)
1042 			pi->aa--;
1043 		}
1044 	    } else
1045 		pi->vram_now[x] = cc;
1046 	} else {
1047 	    if (pi->flag_now[x] < 0) {			/* on chain ? */
1048 		cc = pi->vram_now[x];
1049 		pic2_fast_expand_chain(pi, x, cc);
1050 	    } else if (--pi->aa < 0) {
1051 		cc = pi->vram_now[x] = pic2_fast_read_color(pi, cc);
1052 		pic2_fast_expand_chain(pi, x, cc);
1053 		pi->aa = pic2_fast_read_length(pi);
1054 		if (pi->aa == 1023)
1055 		    pi->dd = 1023;
1056 		else if (pi->aa > 1023)
1057 		    pi->aa--;
1058 	    } else
1059 		pi->vram_now[x] = cc;
1060 	}
1061     }
1062     if (line != NULL)
1063 	*line = pi->vram_now;
1064     pi->ynow++;
1065 
1066     pic2_handle_para(pi, 1);
1067 
1068     return (pi->ynow - 1);
1069 }
1070 
pic2_fast_loader_init(pi)1071 static int pic2_fast_loader_init(pi)
1072 struct pic2_info *pi;
1073 {
1074     int xw;
1075 
1076     pi->ynow = 0;
1077 
1078     /* check the color depth */
1079     if (pi->header->depth % 3)
1080 	pic2_error(pi, PIC2_DEPTH);
1081 
1082     /* set function for extract next line */
1083     pi->next_line = pic2_fast_expand_line;
1084 
1085     /* clear cache and flags */
1086     xw = pi->block->x_wid;
1087     xvbzero((char *) pi->cache, sizeof(pi->cache[0]) * 256);
1088     xvbzero((char *) pi->cache_pos, sizeof(pi->cache_pos[0]) * 8 * 8 * 8);
1089     xvbzero((char *) pi->flag_now, (xw + 8) * sizeof(pi->flag_now[0]));
1090     xvbzero((char *) pi->flag_next, (xw + 8) * sizeof(pi->flag_next[0]));
1091 
1092     /* go to picture data field */
1093     pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET);
1094 
1095     /* clear bit field marker */
1096     pi->bs.rest = 0;
1097     pi->bs.cur = 0;
1098 
1099     return (0);
1100 }
1101 
1102 /*
1103  * These functions are beta pic2 format extractor.
1104  */
pic2_beta_expand_line(pi,line)1105 static int pic2_beta_expand_line(pi, line)
1106 struct pic2_info *pi;
1107 pixel **line;
1108 {
1109     int i, xw, ymax;
1110     byte a, b, c, *p;
1111     pixel *pc;
1112     short depth, pixbyte, colbits;
1113 
1114     depth = pi->header->depth;
1115     pixbyte = depth / 8 + ((depth % 8) > 0);
1116     colbits = depth / 3;
1117 
1118     xw = pi->block->x_wid;
1119     ymax = pi->block->y_wid - 1;
1120 
1121     if (pi->ynow > ymax)
1122 	return (-2);					/* end */
1123 
1124     pc = pi->vram_now;
1125     p = (byte *) pi->vram_prev;
1126     if (pixbyte == 3) {
1127 	pic2_read_file(pi, pi->vram_prev, (size_t) (xw * pixbyte));
1128 	for (i = 0; i < xw; i++, pc++) {
1129 	    a = *p++;
1130 	    b = *p++;
1131 	    c = *p++;
1132 	    *pc = ((pixel) a << 16) | ((pixel) b << 8) | (pixel) c;
1133 	}
1134     } else if (pixbyte == 2) {
1135 	pic2_read_file(pi, pi->vram_prev, (size_t) (xw * 2));
1136 	if (strncmp(pi->block->id, "P2BM", 4) == 0) {
1137 	    for (i = 0; i < xw; i++, pc++) {
1138 		a = *p++;
1139 		b = *p++;
1140 		*pc = ((pixel) a << 8) | (pixel) b;
1141 		if (colbits == 5) {
1142 		    *pc >>= 1;
1143 		    *pc = pic2_exchange_rg(*pc, colbits);
1144 		}
1145 	    }
1146 	} else {
1147 	    for (i = 0; i < xw; i++, pc++) {
1148 		a = *p++;
1149 		b = *p++;
1150 		*pc = ((pixel) b << 8) | (pixel) a;
1151 		if (colbits == 5) {
1152 		    *pc >>= 1;
1153 		    *pc = pic2_exchange_rg(*pc, colbits);
1154 		}
1155 	    }
1156 	}
1157     } else {
1158 	pic2_read_file(pi, pi->vram_prev, (size_t) xw);
1159 	for (i = 0; i < xw; i++)
1160 	    *pc++ = *p++;
1161     }
1162     if (line != NULL)
1163 	*line = pi->vram_now;
1164 
1165     pc = pi->vram_prev;
1166     pi->vram_prev = pi->vram_now;
1167     pi->vram_now = pi->vram_next;
1168     pi->vram_next = pc;
1169 
1170     pi->ynow++;
1171     return (pi->ynow - 1);
1172 }
1173 
pic2_beta_loader_init(pi)1174 static int pic2_beta_loader_init(pi)
1175 struct pic2_info *pi;
1176 {
1177     pi->ynow = 0;
1178     pi->next_line = pic2_beta_expand_line;
1179     pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET);
1180     return (0);
1181 }
1182 
1183 /*
1184  * Make a picture from the expanded data.
1185  */
pic2_make_xvpic(pi,xp,rp,gp,bp)1186 static void pic2_make_xvpic(pi, xp, rp, gp, bp)
1187 struct pic2_info *pi;
1188 byte **xp, *rp, *gp, *bp;
1189 {
1190     int line, i;
1191     pixel *linep, opaque;
1192     short colbits;
1193     byte colmask;
1194 
1195     if (*xp == NULL)
1196 	*xp = pic2_new((size_t) pi->x_max * pi->y_max * 3, "pic2_make_xvpic");   // GRR POSSIBLE OVERFLOW / FIXME
1197 
1198     if (pi->block->flag & 1)
1199 	opaque = pi->block->opaque;
1200     else
1201 	opaque = 0xffffffff;
1202 
1203     colbits = pi->header->depth / 3;
1204     colmask = 0xff >> (8 - colbits);
1205 
1206     line = pic2_load_block(pi);
1207     for (;;) {
1208 	int pic_idx;
1209 
1210 	line = pic2_next_line(pi, &linep);
1211 	if (line < 0)
1212 	    break;
1213 	pic_idx = ((line + pi->block->y_offset) * pi->x_max
1214 		   + pi->block->x_offset) * 3;
1215 
1216 	for (i = 0; i < pi->block->x_wid; i++, linep++) {
1217 	    byte r, g, b;
1218 
1219 	    if (*linep != opaque) {
1220 		r = ((*linep >> (colbits * 2)) & colmask);
1221 		r = pic2_convert_color_bits(r, colbits, 8);
1222 		g = ((*linep >>  colbits     ) & colmask);
1223 		g = pic2_convert_color_bits(g, colbits, 8);
1224 		b = ( *linep                   & colmask);
1225 		b = pic2_convert_color_bits(b, colbits, 8);
1226 		(*xp)[pic_idx++] = r;
1227 		(*xp)[pic_idx++] = g;
1228 		(*xp)[pic_idx++] = b;
1229 	    } else
1230 	        pic_idx += 3;
1231 
1232 	    WaitCursor();
1233 	}
1234     }
1235 }
1236 
1237 /*
1238  * This function splits a multiblock PIC2 file into several pages.
1239  */
pic2_make_pagefile(pi,pagebname,pnum)1240 static void pic2_make_pagefile(pi, pagebname, pnum)
1241 struct pic2_info *pi;
1242 char *pagebname;
1243 int pnum;
1244 {
1245     struct pic2_info pic2;
1246     FILE *fp;
1247     char pagefile[64], *buf;
1248     size_t imagesize;
1249 
1250     sprintf(pagefile, "%s%d", pagebname, pnum);
1251     if ((fp = fopen(pagefile, "wb")) == NULL)
1252 	pic2_error(pi, PIC2_WRITE);
1253 
1254     xvbcopy((char *) pi, (char *) &pic2, sizeof(struct pic2_info));
1255     pic2.fp = fp;
1256 
1257     pic2_write_header1(&pic2);
1258 
1259     pic2_write_block_header(&pic2);
1260 
1261     imagesize = pi->block->size - PIC2_BLOCK_HEADER_SIZE;
1262     buf = (char *) pic2_malloc(imagesize, "pic2_make_pagefile");
1263 
1264     pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET);
1265     if (fread(buf, (size_t) 1, imagesize, pi->fp) < imagesize) {
1266 	free(buf);
1267 	pic2_file_error(pi, PIC2_CORRUPT);
1268     }
1269     if (fwrite(buf, (size_t) 1, imagesize, fp) < imagesize) {
1270 	free(buf);
1271 	pic2_error(pi, PIC2_WRITE);
1272     }
1273     free(buf);
1274 
1275     pic2.next_pos = pic2_tell_file(&pic2);
1276     pic2_write_header2(&pic2);
1277 
1278     fclose(fp);
1279 }
1280 
1281 /* The main routine to save a PIC2 file. */
WritePIC2(fp,pic0,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle,fname,type,depth,x_offset,y_offset,append,comment)1282 static int WritePIC2(fp, pic0, ptype, w, h, rmap, gmap, bmap, numcols,
1283 		     colorstyle, fname, type, depth, x_offset, y_offset,
1284 		     append, comment)
1285 FILE *fp;
1286 byte *pic0;
1287 int ptype, w, h;
1288 byte *rmap, *gmap, *bmap;
1289 int numcols, colorstyle;
1290 char *fname;
1291 int type, depth;
1292 int x_offset, y_offset;
1293 int append;
1294 char *comment;
1295 {
1296     struct pic2_info pic2;
1297     char creator[256], title[256], saver[256];
1298     int e;
1299 
1300     if (DEBUG)
1301 	fputs("WritePIC2:\n", stderr);
1302 
1303     pic2_init_info(&pic2);
1304     pic2.fp = fp;
1305     pic2.writing_grey = (colorstyle == F_GREYSCALE);
1306 
1307     if ((e = setjmp(pic2.jmp)) != 0){
1308 	/* When an error occurs while writing, comes here. */
1309 	pic2_free_buffer(&pic2);
1310 	pic2_cleanup_pic2_info(&pic2, 1);
1311 	SetCursors(-1);
1312 	if (DEBUG)
1313 	    fputs("\n", stderr);
1314 	return (-1);
1315     }
1316     sprintf(creator, "XV Version %s", VERSTR);
1317     pic2_strncpy(title, comment, 30);
1318     sprintf(saver, "XV %s/UNIX/Bradley", VERSTR);
1319 
1320     if (!append) {
1321 	pic2_setup_pic2_info(&pic2, creator, fname, title, saver,
1322 			     0, depth, 1, 1, w, h, comment);
1323 	pic2_write_header1(&pic2);
1324     } else {
1325 	pic2_read_header(&pic2);
1326 	pic2_append(&pic2);
1327 	free(pic2.comment);
1328 	pic2_setup_pic2_info(&pic2, creator, fname, title, saver,
1329 			     0, depth, 1, 1, w, h, comment);
1330     }
1331 
1332     pic2_write_data(&pic2, pic0, ptype, x_offset, y_offset, w, h,
1333 		    rmap, gmap, bmap, type, depth);
1334     pic2_write_header2(&pic2);
1335 
1336     pic2_cleanup_pic2_info(&pic2, 1);
1337     SetCursors(-1);
1338     if (DEBUG)
1339 	fputs("\n", stderr);
1340     return (0);
1341 }
1342 
1343 /*
1344  * This function initializes pic2_info.
1345  */
pic2_setup_pic2_info(pi,name,fname,title,saver,no,depth,x_aspect,y_aspect,x_max,y_max,comment)1346 static void pic2_setup_pic2_info(pi, name, fname, title, saver, no, depth,
1347 			      x_aspect, y_aspect, x_max, y_max, comment)
1348 struct pic2_info *pi;
1349 char *name, *fname, *title, *saver;
1350 int no, depth;
1351 int x_aspect, y_aspect;
1352 int x_max, y_max;
1353 char *comment;
1354 {
1355     char basename[256], *suffix;
1356 
1357     pi->mode = PIC2_WRITE_MODE;
1358 
1359     /* set magic number */
1360     strncpy(pi->header->magic, pic2_id, 4);
1361 
1362     /* set creator's name */
1363     pic2_strncpy(pi->header->name, (char *) name, 18);
1364 
1365     /* set title and subtitle */
1366     pic2_strncpy(pi->header->title, (char *) title, 30);
1367     strcpy(basename, BaseName(fname));
1368     suffix = (char *) rindex(basename, '.');
1369     if (suffix) {
1370 	suffix++;
1371 	if (!strcmp(suffix, "p2") || !strcmp(suffix, "P2"))
1372 	    *(suffix - 1) = '\0';
1373     }
1374     pic2_strncpy(pi->header->subtitle, basename, 8);
1375 
1376     /* set saver */
1377     pic2_strncpy(pi->header->saver, saver, 30);
1378 
1379     /* set picture number */
1380     pi->header->no = no;
1381 
1382     /* import comment */
1383     pi->comment = comment;
1384 
1385     /* set some picture's info */
1386     pi->header->depth = depth;
1387     pi->header->x_aspect = x_aspect;
1388     pi->header->y_aspect = y_aspect;
1389     pi->header->x_max = x_max;
1390     pi->header->y_max = y_max;
1391 
1392     /* set some gaps */
1393     pi->header->crlf0[0] = pi->header->crlf1[0] = pi->header->crlf2[0] = 0x0d;
1394     pi->header->crlf0[1] = pi->header->crlf1[1] = pi->header->crlf2[1] = 0x0a;
1395 
1396     pi->header->eof[0] = 0x1a;
1397     pi->header->reserve0[0] = 0;
1398     pi->header->reserve1 = 0;
1399 
1400     /* set palettes */
1401     if (pi->n_pal > 0)
1402 	pi->header->flag = 1;
1403     else
1404 	pi->header->flag = 0;
1405 }
1406 
1407 /*
1408  * This function appends to existing pic2 file.
1409  */
pic2_append(pi)1410 static void pic2_append(pi)
1411 struct pic2_info *pi;
1412 {
1413     int block;
1414 
1415     block = pic2_find_block(pi);
1416     while (block > 0)
1417 	block = pic2_next_block(pi);
1418 
1419     if (block != 0)
1420 	pic2_error(pi, PIC2_APPEND);
1421 }
1422 
1423 /*
1424  * These functions write the PIC2 header.
1425  * pic2_write_header1:
1426  *	write palette data and comment.
1427  * pic2_write_header2:
1428  *	write the terminate block and rest header.
1429  * pic2_write_block_header:
1430  *	write the block header.
1431  */
pic2_write_header1(pi)1432 static void pic2_write_header1(pi)
1433 struct pic2_info *pi;
1434 {
1435     char *comment;
1436 
1437     /* seek to block start position */
1438     pic2_seek_file(pi, PIC2_HEADER_SIZE, SEEK_SET);
1439 
1440     /* write palette */
1441     if (pi->n_pal > 0) {
1442 	pic2_write_char(pi, pi->pal_bits);
1443 	pic2_write_short(pi, pi->n_pal);
1444 	pic2_write_file(pi, pi->pal, (size_t) (pi->n_pal * 3));
1445     }
1446     /* save comment */
1447     comment = pi->comment;
1448     if (pi->comment != NULL) {
1449 	for (comment = pi->comment; *comment; comment++) {
1450 	    if (*comment == '\n') {
1451 		pic2_write_char(pi, '\r');
1452 		pic2_write_char(pi, '\n');
1453 	    } else if (*comment != '\r')
1454 		pic2_write_char(pi, *comment);
1455 	}
1456 	pic2_write_char(pi, 0);
1457     }
1458     /* set the next block position */
1459     pi->next_pos = pic2_tell_file(pi);
1460     pi->header->size = pi->next_pos;
1461 }
1462 
pic2_write_header2(pi)1463 static void pic2_write_header2(pi)
1464 struct pic2_info *pi;
1465 {
1466     pic2_seek_file(pi, pi->next_pos, SEEK_SET);
1467 
1468     /* write terminate block */
1469     pic2_write_long(pi, 0);
1470     pic2_write_long(pi, 0);
1471 
1472     /* set some header information */
1473     if (pi->header->x_max < pi->x_max)
1474 	pi->header->x_max = pi->x_max;
1475     if (pi->header->y_max < pi->x_max)
1476 	pi->header->y_max = pi->y_max;
1477 
1478     pi->header->time = time(NULL);
1479     pic2_seek_file(pi, 0, SEEK_SET);
1480 
1481     /* write header image */
1482     pic2_write_file(pi, pi->header->magic, 4);
1483     pic2_write_file(pi, pi->header->name, 18);
1484     pic2_write_file(pi, pi->header->subtitle, 8);
1485     pic2_write_file(pi, pi->header->crlf0, 2);
1486     pic2_write_file(pi, pi->header->title, 30);
1487     pic2_write_file(pi, pi->header->crlf1, 2);
1488     pic2_write_file(pi, pi->header->saver, 30);
1489     pic2_write_file(pi, pi->header->crlf2, 2);
1490     pic2_write_file(pi, pi->header->eof, 1);
1491     pic2_write_file(pi, pi->header->reserve0, 1);
1492     pic2_write_short(pi, pi->header->flag);
1493     pic2_write_short(pi, pi->header->no);
1494     pic2_write_long(pi, pi->header->time);
1495     pic2_write_long(pi, pi->header->size);
1496     pic2_write_short(pi, pi->header->depth);
1497     pic2_write_short(pi, pi->header->x_aspect);
1498     pic2_write_short(pi, pi->header->y_aspect);
1499     pic2_write_short(pi, pi->header->x_max);
1500     pic2_write_short(pi, pi->header->y_max);
1501     pic2_write_long(pi, pi->header->reserve1);
1502 }
1503 
pic2_write_block_header(pi)1504 static void pic2_write_block_header(pi)
1505 struct pic2_info *pi;
1506 {
1507     pic2_write_file(pi, pi->block->id, 4);
1508     pic2_write_long(pi, pi->block->size);
1509     pic2_write_short(pi, pi->block->flag);
1510     pic2_write_short(pi, pi->block->x_wid);
1511     pic2_write_short(pi, pi->block->y_wid);
1512     pic2_write_short(pi, pi->block->x_offset);
1513     pic2_write_short(pi, pi->block->y_offset);
1514     pic2_write_long(pi, pi->block->opaque);
1515     pic2_write_long(pi, pi->block->reserve);
1516 }
1517 
1518 /*
1519  * These functions implement the arithmetic-format compressor.
1520  */
1521 #define	pic2_arith_write_one_bit(pi)	(pi->bs.bits++)
1522 
pic2_arith_write_zero_bit(pi)1523 static void pic2_arith_write_zero_bit(pi)
1524 struct pic2_info *pi;
1525 {
1526     if (pi->bs.zero)
1527 	pic2_write_bits(pi, 0, 1);
1528 
1529     while (pi->bs.bits--)
1530 	pic2_write_bits(pi, 1, 1);
1531 
1532     pi->bs.bits = 0;
1533     pi->bs.zero = 1;
1534 }
1535 
pic2_arith_flush_bit_buf(pi)1536 static void pic2_arith_flush_bit_buf(pi)
1537 struct pic2_info *pi;
1538 {
1539     int	i;
1540 
1541     for (i = 0; i < 16; i++) {
1542 	if (pi->cc & 0x8000)
1543 	    pic2_arith_write_one_bit(pi);
1544 	else
1545 	    pic2_arith_write_zero_bit(pi);
1546 	pi->cc <<= 1;
1547     }
1548     pic2_arith_write_zero_bit(pi);
1549     pic2_flush_bits(pi);
1550 }
1551 
pic2_arith_carry_bit(pi)1552 static void pic2_arith_carry_bit(pi)
1553 struct pic2_info *pi;
1554 {
1555     pic2_write_bits(pi, 1, 1);
1556 
1557     if (pi->bs.bits == 0) {
1558 	pi->bs.zero = 0;
1559     } else {
1560 	while (--pi->bs.bits)
1561 	    pic2_write_bits(pi, 0, 1);
1562 	pi->bs.zero = 1;
1563     }
1564 }
1565 
pic2_arith_encode_bit(pi,n,c)1566 static void pic2_arith_encode_bit(pi, n, c)
1567 struct pic2_info *pi;
1568 int n, c;
1569 {
1570     int	pp;
1571     long *c_sum, *c_0_sum;
1572 
1573     c_sum = (long *) pi->mulu_tab;
1574     c_0_sum = c_sum + PIC2_ARITH_CONTEXT + 1;
1575 
1576     if (pi->dd  == 0) {
1577 	c_sum[c]++;
1578 	if (n == 0)
1579 	    c_0_sum[c]++;
1580 	return;
1581     }
1582     pp = pi->mulu_tab[(pi->aa & 0x7f00) / 2 + c];
1583     if (n != 0) {
1584 	pi->cc = pi->cc + pp;
1585 	if (pi->cc > 0xffff) {
1586 	    pic2_arith_carry_bit(pi);
1587 	    pi->cc = pi->cc & 0xffff;
1588 	}
1589 	pi->aa = pi->aa - pp;
1590 	while (pi->aa < 0x8000) {
1591 	    if (pi->cc & 0x8000)
1592 		pic2_arith_write_one_bit(pi);
1593 	    else
1594 		pic2_arith_write_zero_bit(pi);
1595 	    pi->cc = (pi->cc * 2) & 0xffff;
1596 	    pi->aa = pi->aa * 2;
1597 	}
1598     } else {
1599 	pi->aa = pp;
1600 
1601 	while (pi->aa < 0x8000) {
1602 	    if (pi->cc & 0x8000)
1603 		pic2_arith_write_one_bit(pi);
1604 	    else
1605 		pic2_arith_write_zero_bit(pi);
1606 	    pi->cc = (pi->cc * 2) & 0xffff;
1607 	    pi->aa = pi->aa * 2;
1608 	}
1609     }
1610 }
1611 
pic2_arith_encode_nbyte(pi,n,c,max)1612 static void pic2_arith_encode_nbyte(pi, n, c, max)
1613 struct pic2_info *pi;
1614 int n, c, max;
1615 {
1616     short i;
1617 
1618     for (i = 0; i < n; i++) {
1619 	pic2_arith_encode_bit(pi, 0, c + i);
1620     }
1621     if (n < max)
1622 	pic2_arith_encode_bit(pi, 1, c + n);
1623 }
1624 
pic2_arith_encode_nn(pi,n,c)1625 static void pic2_arith_encode_nn(pi, n, c)
1626 struct pic2_info *pi;
1627 int n, c;
1628 {
1629     if (n < 1) {
1630 	pic2_arith_encode_bit(pi, 1, c);
1631     } else if (n < 1 + 2) {
1632 	pic2_arith_encode_bit(pi, 0, c);
1633 	pic2_arith_encode_bit(pi, 1, c + 1);
1634 	n -= 1;
1635 	pic2_arith_encode_bit(pi, n & 1, c + 8);
1636     } else if (n < 1 + 2 + 4) {
1637 	pic2_arith_encode_bit(pi, 0, c);
1638 	pic2_arith_encode_bit(pi, 0, c + 1);
1639 	pic2_arith_encode_bit(pi, 1, c + 2);
1640 	n -= 1 + 2;
1641 	pic2_arith_encode_bit(pi, n & 1, c + 8);
1642 	pic2_arith_encode_bit(pi, n & 2, c + 9);
1643     } else if (n < 1 + 2 + 4 + 8) {
1644 	pic2_arith_encode_bit(pi, 0, c);
1645 	pic2_arith_encode_bit(pi, 0, c + 1);
1646 	pic2_arith_encode_bit(pi, 0, c + 2);
1647 	pic2_arith_encode_bit(pi, 1, c + 3);
1648 	n -= 1 + 2 + 4;
1649 	pic2_arith_encode_bit(pi, n & 1, c + 8);
1650 	pic2_arith_encode_bit(pi, n & 2, c + 9);
1651 	pic2_arith_encode_bit(pi, n & 4, c + 10);
1652     } else if (n < 1 + 2 + 4 + 8 + 16) {
1653 	pic2_arith_encode_bit(pi, 0, c);
1654 	pic2_arith_encode_bit(pi, 0, c + 1);
1655 	pic2_arith_encode_bit(pi, 0, c + 2);
1656 	pic2_arith_encode_bit(pi, 0, c + 3);
1657 	pic2_arith_encode_bit(pi, 1, c + 4);
1658 	n -= 1 + 2 + 4 + 8;
1659 	pic2_arith_encode_bit(pi, n & 1, c + 8);
1660 	pic2_arith_encode_bit(pi, n & 2, c + 9);
1661 	pic2_arith_encode_bit(pi, n & 4, c + 10);
1662 	pic2_arith_encode_bit(pi, n & 8, c + 11);
1663     } else if (n < 1 + 2 + 4 + 8 + 16 + 32) {
1664 	pic2_arith_encode_bit(pi, 0, c);
1665 	pic2_arith_encode_bit(pi, 0, c + 1);
1666 	pic2_arith_encode_bit(pi, 0, c + 2);
1667 	pic2_arith_encode_bit(pi, 0, c + 3);
1668 	pic2_arith_encode_bit(pi, 0, c + 4);
1669 	pic2_arith_encode_bit(pi, 1, c + 5);
1670 	n -= 1 + 2 + 4 + 8 + 16;
1671 	pic2_arith_encode_bit(pi, n & 1, c + 8);
1672 	pic2_arith_encode_bit(pi, n & 2, c + 9);
1673 	pic2_arith_encode_bit(pi, n & 4, c + 10);
1674 	pic2_arith_encode_bit(pi, n & 8, c + 11);
1675 	pic2_arith_encode_bit(pi, n & 16, c + 12);
1676     } else if (n < 1 + 2 + 4 + 8 + 16 + 32 + 64) {
1677 	pic2_arith_encode_bit(pi, 0, c);
1678 	pic2_arith_encode_bit(pi, 0, c + 1);
1679 	pic2_arith_encode_bit(pi, 0, c + 2);
1680 	pic2_arith_encode_bit(pi, 0, c + 3);
1681 	pic2_arith_encode_bit(pi, 0, c + 4);
1682 	pic2_arith_encode_bit(pi, 0, c + 5);
1683 	pic2_arith_encode_bit(pi, 1, c + 6);
1684 	n -= 1 + 2 + 4 + 8 + 16 + 32;
1685 	pic2_arith_encode_bit(pi, n & 1, c + 8);
1686 	pic2_arith_encode_bit(pi, n & 2, c + 9);
1687 	pic2_arith_encode_bit(pi, n & 4, c + 10);
1688 	pic2_arith_encode_bit(pi, n & 8, c + 11);
1689 	pic2_arith_encode_bit(pi, n & 16, c + 12);
1690 	pic2_arith_encode_bit(pi, n & 32, c + 13);
1691     } else if (n < 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128) {
1692 	pic2_arith_encode_bit(pi, 0, c);
1693 	pic2_arith_encode_bit(pi, 0, c + 1);
1694 	pic2_arith_encode_bit(pi, 0, c + 2);
1695 	pic2_arith_encode_bit(pi, 0, c + 3);
1696 	pic2_arith_encode_bit(pi, 0, c + 4);
1697 	pic2_arith_encode_bit(pi, 0, c + 5);
1698 	pic2_arith_encode_bit(pi, 0, c + 6);
1699 	pic2_arith_encode_bit(pi, 1, c + 7);
1700 	n -= 1 + 2 + 4 + 8 + 16 + 32 + 64;
1701 	pic2_arith_encode_bit(pi, n & 1, c + 8);
1702 	pic2_arith_encode_bit(pi, n & 2, c + 9);
1703 	pic2_arith_encode_bit(pi, n & 4, c + 10);
1704 	pic2_arith_encode_bit(pi, n & 8, c + 11);
1705 	pic2_arith_encode_bit(pi, n & 16, c + 12);
1706 	pic2_arith_encode_bit(pi, n & 32, c + 13);
1707 	pic2_arith_encode_bit(pi, n & 64, c + 14);
1708     } else {
1709 	pic2_arith_encode_bit(pi, 0, c);
1710 	pic2_arith_encode_bit(pi, 0, c + 1);
1711 	pic2_arith_encode_bit(pi, 0, c + 2);
1712 	pic2_arith_encode_bit(pi, 0, c + 3);
1713 	pic2_arith_encode_bit(pi, 0, c + 4);
1714 	pic2_arith_encode_bit(pi, 0, c + 5);
1715 	pic2_arith_encode_bit(pi, 0, c + 6);
1716 	pic2_arith_encode_bit(pi, 0, c + 7);
1717     }
1718 }
1719 
pic2_arith_press_chain(pi,x)1720 static void pic2_arith_press_chain(pi, x)
1721 struct pic2_info *pi;
1722 int x;
1723 {
1724     int b, d;
1725     pixel c;
1726 
1727     b = -(pi->flag_now[x]);
1728     c = pi->vram_now[x];
1729     d = 0;
1730 
1731     if (b < 0)
1732 	b = 0;
1733 
1734     if (pi->flag_next[x] == 1 && pi->vram_next[x] == c) {
1735 	d = 1;
1736 	pi->flag_next[x] = -1;
1737     } else if (pi->flag_next[x - 1] == 1 && pi->vram_next[x - 1] == c) {
1738 	d = 2;
1739 	pi->flag_next[x - 1] = -2;
1740     } else if (pi->flag_next[x + 1] == 1 && pi->vram_next[x + 1] == c) {
1741 	d = 3;
1742 	pi->flag_next[x + 1] = -3;
1743     } else if (pi->flag_next[x - 2] == 1 && pi->vram_next[x - 2] == c) {
1744 	d = 4;
1745 	pi->flag_next[x - 2] = -4;
1746     } else if (pi->flag_next[x + 2] == 1 && pi->vram_next[x + 2] == c) {
1747 	if ((pi->flag_now[x + 2] != 0 && pi->vram_now[x + 2] == c)
1748 	    || (pi->flag_now[x + 1] != 0 && pi->vram_now[x + 1] == c)
1749 	    || (pi->flag_now[x + 3] != 0 && pi->vram_now[x + 3] == c)) {
1750 	    pic2_arith_encode_nbyte(pi, 0, 80 + 6 * b, 5);
1751 	    return;
1752 	}
1753 	d = 5;
1754 	pi->flag_next[x + 2] = -5;
1755     }
1756     pic2_arith_encode_nbyte(pi, d, 80 + 6 * b, 5);
1757 }
1758 
pic2_arith_put_number(pi,xn,xa,xb)1759 static void pic2_arith_put_number(pi, xn, xa, xb)
1760 struct pic2_info *pi;
1761 int xn, xa, xb;
1762 {
1763     short n;
1764     byte maxcol;
1765 
1766     maxcol = 0xff >> (8 - pi->header->depth / 3);
1767 
1768     if (xa > ((int) maxcol >> 1)) {
1769 	if (xb > xa)
1770 	    n = (xb - xa) * 2 - 1;
1771 	else if (xa - ((int) maxcol - xa)  > xb)
1772 	    n = maxcol - xb;
1773 	else
1774 	    n = (xa - xb) * 2;
1775     } else {
1776 	if (xb <= xa)
1777 	    n = (xa - xb) * 2;
1778 	else if (2 * xa < xb)
1779 	    n = xb;
1780  	else
1781 	    n = (xb - xa) * 2 - 1;
1782     }
1783     pic2_arith_encode_nn(pi, n, xn);
1784 }
1785 
pic2_arith_write_color(pi,x)1786 static void pic2_arith_write_color(pi, x)
1787 struct pic2_info *pi;
1788 int x;
1789 {
1790     pixel c1, c2, cc;
1791     short g0, r0, b0, r, g, b;
1792     int i, j;
1793     unsigned short k;
1794     pixel *p, *pp;
1795     short colbits;
1796     pixel rmask, gmask, bmask;
1797     byte maxcol;
1798 
1799     colbits = pi->header->depth / 3;
1800     rmask = (0xff >> (8 - colbits)) << (colbits * 2);
1801     gmask = (0xff >> (8 - colbits)) <<  colbits;
1802     bmask = (0xff >> (8 - colbits));
1803     maxcol = (byte) bmask;
1804 
1805     cc = pi->vram_now[x];
1806     c1 = pi->vram_prev[x];
1807     k = ((c1 >> ((colbits - 3) * 3)) & 0x1c0)
1808       | ((c1 >> ((colbits - 3) * 2)) & 0x038)
1809       | ((c1 >>  (colbits - 3)     ) & 0x007);
1810     if (colbits == 5)
1811 	k = pic2_exchange_rg(k, 3);
1812 
1813     p = pi->cache[k];
1814     for (i = 0; i < (PIC2_ARITH_CACHE - 1); i++) {
1815 	if (cc == *p++)
1816 	    break;
1817     }
1818     if (i == (PIC2_ARITH_CACHE - 1)) {
1819 	pp = p - 1;
1820 	for (j = i; j > 0; j--) {
1821 	    *--p = *--pp;
1822 	}
1823 	pi->cache[k][0] = cc;
1824 	pic2_arith_encode_bit(pi, 1, pi->cache_hit_c);
1825 	pi->cache_hit_c = 16;
1826 
1827 	c2 = pi->vram_now[x - 1];
1828 	r = ((c1 & rmask) + (c2 & rmask)) >> (colbits * 2 + 1);
1829 	g = ((c1 & gmask) + (c2 & gmask)) >> (colbits     + 1);
1830 	b = ((c1 & bmask) + (c2 & bmask)) >> (              1);
1831 
1832 	r0 = (cc >> (colbits * 2)) & maxcol;
1833 	g0 = (cc >>  colbits     ) & maxcol;
1834 	b0 =  cc                   & maxcol;
1835 
1836 	r = r + g0 - g;
1837 	if (r < 0)
1838 	    r = 0;
1839 	else if (r > (short) maxcol)
1840 	    r = maxcol;
1841 
1842 	b = b + g0 - g;
1843 	if (b < 0)
1844 	    b = 0;
1845 	else if (b > (short) maxcol)
1846 	    b = maxcol;
1847 
1848 	pic2_arith_put_number(pi, 32, g, g0);
1849 	pic2_arith_put_number(pi, 48, r, r0);
1850 	pic2_arith_put_number(pi, 64, b, b0);
1851     } else {
1852 	*--p = pi->cache[k][i / 2];
1853 	pi->cache[k][i / 2] = pi->cache[k][0];
1854 	pi->cache[k][0] = cc;
1855 
1856 	pic2_arith_encode_bit(pi, 0, pi->cache_hit_c);
1857 	pi->cache_hit_c = 15;
1858 	pic2_arith_encode_nn(pi, i, 17);
1859     }
1860 }
1861 
pic2_arith_press_line2(pi)1862 static void pic2_arith_press_line2(pi)
1863 struct pic2_info *pi;
1864 {
1865     int x, xw, ymax;
1866     pixel cc;
1867 
1868     xw = pi->block->x_wid;
1869     ymax = pi->block->y_wid -1;
1870     cc = pi->vram_now[xw - 1];			/* last color */
1871     pi->vram_next[-1] = cc;
1872 
1873     /* mark change point */
1874     for (x = 0; x < xw; x++)
1875 	if (cc != pi->vram_next[x]) {
1876 	    pi->flag_next[x] = 1;
1877 	    cc = pi->vram_next[x];
1878 	} else
1879 	    pi->flag_next[x] = 0;
1880 
1881     for (x = 0; x < xw; x++) {
1882 	if (pi->flag_now[x] == 1) {			/* change point */
1883 	    pi->flag2_now  [x + 1]++;
1884 	    pi->flag2_now  [x + 2]++;
1885 	    pi->flag2_next [x - 1]++;
1886 	    pi->flag2_next [x    ]++;
1887 	    pi->flag2_next [x + 1]++;
1888 	    pi->flag2_next2[x - 1]++;
1889 	    pi->flag2_next2[x    ]++;
1890 	    pi->flag2_next2[x + 1]++;
1891 
1892 	    /* write change point */
1893 	    pic2_arith_encode_bit(pi, 1, pi->flag2_now[x]);
1894 
1895 	    /* write color */
1896 	    pic2_arith_write_color(pi, x);
1897 
1898 	    /* if not last line, write chain */
1899 	    if (pi->ynow - 1 < ymax)
1900 		pic2_arith_press_chain(pi, x);
1901 	} else if (pi->flag_now[x] == 0)		/* not on chain */
1902 	    /* write change point */
1903 	    pic2_arith_encode_bit(pi, 0, pi->flag2_now[x]);
1904 	else				/* on chain */
1905 	     /* if not on last line, write next chain */
1906 	     if (pi->ynow - 1 < ymax)
1907 		 pic2_arith_press_chain(pi, x);
1908     }
1909 }
1910 
pic2_arith_press_line(pi,line)1911 static int pic2_arith_press_line(pi, line)
1912 struct pic2_info *pi;
1913 pixel **line;
1914 {
1915     int i, xw, ymax;
1916     long *c_sum, *c_0_sum;
1917 
1918     xw = pi->block->x_wid;
1919     ymax = pi->block->y_wid -1;
1920     c_sum = (long *) pi->mulu_tab;
1921     c_0_sum = c_sum + PIC2_ARITH_CONTEXT +1;
1922 
1923     pic2_handle_para(pi, 0);
1924 
1925     xvbzero((char *) pi->flag2_next2 - 4,
1926 	    (8 + xw) * sizeof(pi->flag2_next2[0]));
1927 
1928     if (pi->ynow == 0) {			/* first line */
1929 	int x;
1930 	pixel cc = 0;
1931 
1932 	if (pi->dd != 0) {			/* compress pass */
1933 	    unsigned short c_tab[PIC2_ARITH_CONTEXT];
1934 
1935 	    for (i = 0; i < PIC2_ARITH_CONTEXT; i++) {
1936 		unsigned long a, b;
1937 		a = c_0_sum[i];
1938 		b = c_sum[i];
1939 		while (a > 32767) {
1940 		    a /= 2;
1941 		    b /= 2;
1942 		}
1943 		if (a == b)
1944 		    c_tab[i] = 0xffff;		/* b==0 here, too */
1945 		else
1946 		    c_tab[i] = (65536 * a) / b; /* a < b, so less 65536 */
1947 	    }
1948 	    for (i = 0; i < 16384; i++) {
1949 		pi->mulu_tab[i] = (long) (i / 128 + 128) * (int) c_tab[i & 127] / 256;
1950 		if (pi->mulu_tab[i] == 0)
1951 		    pi->mulu_tab[i] = 1;	/* 0 is wrong */
1952 	    }
1953 	    for (i = 0; i < PIC2_ARITH_CONTEXT; i++)
1954 		pic2_write_short(pi, c_tab[i]);
1955 
1956 	    xvbzero((char *) pi->vram_now, xw * sizeof(pi->vram_now[0]));
1957 	} else {				/* statistical pass */
1958 	    xvbzero((char *) c_0_sum, PIC2_ARITH_CONTEXT * sizeof(c_0_sum[0]));
1959 	    xvbzero((char *) c_sum, PIC2_ARITH_CONTEXT * sizeof(c_sum[0]));
1960 	}
1961 
1962 	/* initialize flags */
1963 	xvbzero((char *) pi->cache, 8 * 8 * 8 * sizeof(pi->cache[0]));
1964 	xvbzero((char *) pi->cache_pos, 8 * 8 * 8 * sizeof(pi->cache_pos[0]));
1965 
1966 	xvbzero((char *) pi->flag2_next - 4,
1967 		(8 + xw) * sizeof(pi->flag2_next[0]));
1968 	xvbzero((char *) pi->flag2_next2 - 4,
1969 		(8 + xw) * sizeof(pi->flag2_next2[0]));
1970 
1971 	pi->vram_next[-1] = cc;
1972 	for (x = 0; x < xw; x++)
1973 	    if (cc != pi->vram_next[x]) {
1974 		pi->flag_next[x] = 1;
1975 		cc = pi->vram_next[x];
1976 	    } else
1977 		pi->flag_next[x] = 0;
1978 
1979 	pi->aa = 0xffff;
1980 	cc = 0;
1981 	pi->cache_hit_c = 16;
1982     } else					/* after second line */
1983 	pic2_arith_press_line2(pi);
1984 
1985     if (pi->ynow ==  ymax) {
1986 	pi->ynow++;
1987 	pic2_handle_para(pi, 1);
1988 	pic2_handle_para(pi, 0);
1989 	pic2_arith_press_line2(pi);
1990     }
1991     /* line buffer for next data */
1992     if (line != NULL)
1993 	*line = pi->vram_prev;
1994 
1995     pi->ynow++;
1996 
1997     if (pi->ynow - 1 < ymax) {
1998 	pic2_handle_para(pi, 1);
1999 	return (pi->ynow);
2000     } else {					/* end */
2001 	if (pi->dd == 0) {			/* statistical pass */
2002 	    pi->dd = 1;
2003 	    pi->ynow = 0;
2004 	    pic2_handle_para(pi, 1);
2005 	    return (0);
2006 	} else {
2007 	    pic2_handle_para(pi, 1);
2008 	    pic2_arith_flush_bit_buf(pi);
2009 	    return (-2);			/* end */
2010 	}
2011     }
2012 }
2013 
pic2_arith_saver_init(pi,line)2014 static int pic2_arith_saver_init(pi, line)
2015 struct pic2_info *pi;
2016 pixel **line;
2017 {
2018     pi->ynow = 0;
2019 
2020     /* check the color depth */
2021     if (pi->header->depth % 3)
2022 	pic2_error(pi, PIC2_DEPTH);
2023 
2024     /* set next line function */
2025     pi->next_line = pic2_arith_press_line;
2026 
2027     if (line != NULL)
2028 	*line = pi->vram_next + 4;
2029 
2030     pic2_seek_file(pi, pi->next_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET);
2031 
2032     /* clear bit field marker */
2033     pi->bs.rest = 0;
2034     pi->bs.cur = 0;
2035     pi->bs.zero = 0;
2036     pi->bs.bits = 0;
2037 
2038     return (0);
2039 }
2040 
2041 /*
2042  * These functions are fast pic2 format compressor.
2043  */
pic2_fast_write_length(pi,n)2044 static void pic2_fast_write_length(pi, n)
2045 struct pic2_info *pi;
2046 int n;
2047 {
2048     int	a, b;
2049     static const unsigned short len_data[8][2] = {
2050 	{1, 0},
2051 	{1, 0},
2052 	{3, 4},
2053 	{3, 5},
2054 	{5, 24},
2055 	{5, 25},
2056 	{5, 26},
2057 	{5, 27},
2058     };
2059 
2060     n++;
2061     if (n < 8)
2062 	pic2_write_bits(pi, len_data[n][1], len_data[n][0]);
2063     else {
2064 	a = 0;
2065 	b = 2;
2066 	while (n > b - 1) {
2067 	    a = a + 1;
2068 	    b = b * 2;
2069 	}
2070 	pic2_write_bits(pi, 0xfffffffe, a + 1);
2071 	if (a > 0)
2072 	    pic2_write_bits(pi, n - b / 2, a);
2073     }
2074 }
2075 
pic2_fast_press_chain(pi,x)2076 static void pic2_fast_press_chain(pi, x)
2077 struct pic2_info *pi;
2078 int x;
2079 {
2080     int ymax;
2081     pixel cc;
2082 
2083     ymax = pi->block->y_wid -1;
2084     cc = pi->vram_now[x];
2085 
2086     if (pi->ynow - 1 == ymax) {
2087 	pic2_write_bits(pi, 0, 1);
2088 	return;
2089     }
2090     if (pi->flag_next[x] == 1 && pi->vram_next[x] == cc) {
2091 	pi->flag_next[x] = -1;
2092 	pic2_write_bits(pi, 3, 2);
2093     } else if (pi->flag_next[x - 1] == 1 && pi->vram_next[x - 1] == cc) {
2094 	pi->flag_next[x - 1] = -1;
2095 	pic2_write_bits(pi, 11, 4);
2096     } else if (pi->flag_next[x + 1] == 1 && pi->vram_next[x + 1] == cc) {
2097 	pi->flag_next[x + 1] = -1;
2098 	pic2_write_bits(pi, 9, 4);
2099     } else if (pi->flag_next[x - 2] == 1 && pi->vram_next[x - 2] == cc) {
2100 	pi->flag_next[x - 2] = -1;
2101 	pic2_write_bits(pi, 10, 4);
2102     } else if ((pi->flag_next[x + 2] == 1 && pi->vram_next[x + 2] == cc)
2103 		&& !(pi->flag_now[x + 2] != 0 && pi->vram_now[x + 2] == cc)) {
2104 	pi->flag_next[x + 2] = -1;
2105 	pic2_write_bits(pi, 8, 4);
2106     } else
2107 	pic2_write_bits(pi, 0, 1);
2108 }
2109 
pic2_fast_press_chain2(pi,x)2110 static void pic2_fast_press_chain2(pi, x)
2111 struct pic2_info *pi;
2112 int x;
2113 {
2114     int ymax;
2115     pixel cc;
2116     char *chain_buff;
2117 
2118     ymax = pi->block->y_wid -1;
2119     chain_buff = (char *) pi->mulu_tab;
2120     cc = pi->vram_now[x];
2121 
2122     if (pi->ynow - 1 == ymax) {
2123 	chain_buff[pi->cc++] = 0;
2124 	return;
2125     }
2126     if (pi->flag_next[x] == 1 && pi->vram_next[x] == cc) {
2127 	pi->flag_next[x] = -1;
2128 	chain_buff[pi->cc++] = 1;
2129     } else if (pi->flag_next[x - 1] == 1 && pi->vram_next[x - 1] == cc) {
2130 	pi->flag_next[x - 1] = -1;
2131 	chain_buff[pi->cc++] = 2;
2132     } else if (pi->flag_next[x + 1] == 1 && pi->vram_next[x + 1] == cc) {
2133 	pi->flag_next[x + 1] = -1;
2134 	chain_buff[pi->cc++] = 3;
2135     } else if (pi->flag_next[x - 2] == 1 && pi->vram_next[x - 2] == cc) {
2136 	pi->flag_next[x - 2] = -1;
2137 	chain_buff[pi->cc++] = 4;
2138     } else if ((pi->flag_next[x + 2] == 1 && pi->vram_next[x + 2] == cc)
2139 	       && !(pi->flag_now[x + 2] != 0 && pi->vram_now[x + 2] == cc)) {
2140 	pi->flag_next[x + 2] = -1;
2141 	chain_buff[pi->cc++] = 5;
2142     } else
2143 	chain_buff[pi->cc++] = 0;
2144 }
2145 
pic2_fast_flush_chain(pi)2146 static void pic2_fast_flush_chain(pi)
2147 struct pic2_info *pi;
2148 {
2149     int i;
2150     char *chain_buf;
2151 
2152     chain_buf = (char *) pi->mulu_tab;
2153     for (i = 0; i < pi->cc; i++){
2154 	switch (chain_buf[i]) {
2155 	case 0:
2156 	    pic2_write_bits(pi, 0, 1);
2157 	    break;
2158 	case 1:
2159 	    pic2_write_bits(pi, 3, 2);
2160 	    break;
2161 	case 2:
2162 	    pic2_write_bits(pi, 11, 4);
2163 	    break;
2164 	case 3:
2165 	    pic2_write_bits(pi, 9, 4);
2166 	    break;
2167 	case 4:
2168 	    pic2_write_bits(pi, 10, 4);
2169 	    break;
2170 	case 5:
2171 	    pic2_write_bits(pi, 8, 4);
2172 	    break;
2173 	}
2174     }
2175     pi->cc = 0;
2176 }
2177 
pic2_fast_write_color(pi,x)2178 static void pic2_fast_write_color(pi, x)
2179 struct pic2_info *pi;
2180 int x;
2181 {
2182     pixel cc, bc;
2183     unsigned short j, k, m;
2184     short depth, colbits;
2185     pixel (*cache)[PIC2_FAST_CACHE];
2186 
2187     depth = pi->header->depth;
2188     colbits = depth / 3;
2189     cache = (pixel (*)[PIC2_FAST_CACHE]) pi->cache;
2190 
2191     bc = pi->vram_now[x - 1];
2192     bc = pic2_exchange_rg(bc, colbits);
2193     k = pic2_shift_bits(bc, 8 - depth);
2194     cc = pi->vram_now[x];
2195     m = pi->cache_pos[k];
2196 
2197     for (j = 0; j < PIC2_FAST_CACHE; j++)
2198 	if (cache[k][(m + j) & (PIC2_FAST_CACHE - 1)] == cc)
2199 	    break;
2200 
2201     if (j == PIC2_FAST_CACHE) {
2202 	m = (m - 1) & (PIC2_FAST_CACHE - 1);
2203 	pi->cache_pos[k] = m;
2204 	cache[k][m] = cc;
2205 
2206 	cc = pic2_exchange_rg(cc, colbits);
2207 	pic2_write_bits(pi, 0, 1);
2208 	pic2_write_bits(pi, cc, depth);
2209     } else {
2210 	pic2_write_bits(pi, 1, 1);
2211 	pic2_write_bits(pi, j, 6);
2212     }
2213 }
2214 
pic2_fast_press_line2(pi)2215 static void pic2_fast_press_line2(pi)
2216 struct pic2_info *pi;
2217 {
2218     int x, xw;
2219     pixel cc;
2220 
2221     xw = pi->block->x_wid;
2222     cc = pi->vram_now[xw - 1];			/* last color */
2223     pi->vram_next[-1] = cc;
2224 
2225     /* mark change point */
2226     for (x = 0; x < xw; x++)
2227 	if (cc != pi->vram_next[x]) {
2228 	    pi->flag_next[x] = 1;
2229 	    cc = pi->vram_next[x];
2230 	} else
2231 	    pi->flag_next[x] = 0;
2232 
2233     for (x = 0; x < xw; x++)
2234 	if (pi->flag_now[x] == 1) {			/* change point */
2235 	    if (pi->aa >= 1023)
2236 		pi->aa++;
2237 	    pic2_fast_write_length(pi, pi->aa);
2238 	    pic2_fast_flush_chain(pi);
2239 	    pi->aa = 0;
2240 	    pic2_fast_write_color(pi, x);
2241 	    pic2_fast_press_chain(pi, x);
2242 	} else if (pi->flag_now[x] == 0) {
2243 	    pi->aa++;
2244 	} else {
2245 	    pic2_fast_press_chain2(pi, x);
2246 	    if (pi->cc == 1023) {
2247 		pic2_fast_write_length(pi, 1023);
2248 		pic2_fast_flush_chain(pi);
2249 		pi->aa = 0;
2250 	    }
2251 	}
2252 }
2253 
pic2_fast_press_line(pi,line)2254 static int pic2_fast_press_line(pi, line)
2255 struct pic2_info *pi;
2256 pixel **line;
2257 {
2258     int xw, ymax;
2259 
2260     xw = pi->block->x_wid;
2261     ymax = pi->block->y_wid -1;
2262 
2263     pic2_handle_para(pi, 0);
2264 
2265     if (pi->ynow == 0) {			/* first line */
2266 	int x;
2267 	pixel cc = 0;
2268 
2269 	/* initialize flags */
2270 	xvbzero((char *) pi->cache, 256 * sizeof(pi->cache[0]));
2271 	xvbzero((char *) pi->cache_pos,
2272 		PIC2_FAST_CACHE * sizeof(pi->cache_pos[0]));
2273 
2274 	/* mark change point */
2275 	pi->vram_next[-1] = cc;
2276 	for (x = 0; x < xw; x++)
2277 	    if (cc != pi->vram_next[x]) {
2278 		pi->flag_next[x] = 1;
2279 		cc = pi->vram_next[x];
2280 	    } else
2281 		pi->flag_next[x] = 0;
2282 
2283 	pi->cc = 0;
2284 	pi->aa = 0;
2285     } else					/* after second line */
2286 	pic2_fast_press_line2(pi);
2287 
2288     if (pi->ynow ==  ymax) {
2289 	pi->ynow++;
2290 	pic2_handle_para(pi, 1);
2291 	pic2_handle_para(pi, 0);
2292 	pic2_fast_press_line2(pi);
2293     }
2294     /* line buffer for next data */
2295     if (line != NULL)
2296 	*line = pi->vram_prev;
2297 
2298     pi->ynow++;
2299 
2300     if (pi->ynow - 1 < ymax) {
2301 	pic2_handle_para(pi, 1);
2302 	return (pi->ynow);
2303     } else {					/* end */
2304 	pic2_handle_para(pi, 1);
2305 	if (pi->aa >= 1023)
2306 	    pi->aa++;
2307 	pic2_fast_write_length(pi, pi->aa);
2308 	pic2_fast_flush_chain(pi);
2309 	return (-2);				/* end */
2310     }
2311 }
2312 
pic2_fast_saver_init(pi,line)2313 static int pic2_fast_saver_init(pi, line)
2314 struct pic2_info *pi;
2315 pixel **line;
2316 {
2317     pi->ynow = 0;
2318 
2319     /* check the color depth */
2320     if (pi->header->depth % 3)
2321 	pic2_error(pi, PIC2_DEPTH);
2322 
2323     /* set next line function */
2324     pi->next_line = pic2_fast_press_line;
2325     if (line != NULL)
2326 	*line = pi->vram_next + 4;
2327 
2328     pic2_seek_file(pi, pi->next_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET);
2329 
2330     /* clear bit field marker */
2331     pi->bs.rest = 0;
2332     pi->bs.cur = 0;
2333 
2334     return (0);
2335 }
2336 
2337 /*
2338  * These functions are beta pic2 format compressor.
2339  */
pic2_beta_press_line(pi,line)2340 static int pic2_beta_press_line(pi, line)
2341 struct pic2_info *pi;
2342 pixel **line;
2343 {
2344     int i, xw, ymax;
2345     byte *p;
2346     pixel *pc;
2347     short depth, pixbyte, colbits;
2348 
2349     depth = pi->header->depth;
2350     pixbyte = depth / 8 + ((depth % 8) > 0);
2351     colbits = depth / 3;
2352 
2353     xw = pi->block->x_wid;
2354     ymax = pi->block->y_wid - 1;
2355 
2356     pc = pi->vram_now;
2357     p = (byte *) pi->vram_prev;
2358     if (pixbyte == 3) {
2359 	for (i = 0; i < xw; i++, pc++) {
2360 	    *p++ = *pc >> 16;
2361 	    *p++ = *pc >>  8;
2362 	    *p++ = *pc;
2363 	}
2364 	pic2_write_file(pi, pi->vram_prev, (size_t) (xw * 3));
2365     } else if (pixbyte == 2) {
2366 	if (strncmp(pi->block->id, "P2BM", 4) == 0)
2367 	    for (i = 0; i < xw; i++, pc++) {
2368 		if (colbits == 5) {
2369 		    *pc = pic2_exchange_rg(*pc, colbits);
2370 		    *pc <<= 1;
2371 		}
2372 		*p++ = *pc >> 8;
2373 		*p++ = *pc;
2374 	    }
2375 	else
2376 	    for (i = 0; i < xw; i++, pc++) {
2377 		if (colbits == 5) {
2378 		    *pc = pic2_exchange_rg(*pc, colbits);
2379 		    *pc <<= 1;
2380 		}
2381 		*p++ = *pc;
2382 		*p++ = *pc >> 8;
2383 	    }
2384 	pic2_write_file(pi, pi->vram_prev, (size_t) (xw * 2));
2385     } else {
2386 	for (i = 0; i < xw; i++, pc++)
2387 	    *p++ = *pc;
2388 	pic2_write_file(pi, pi->vram_prev, (size_t) xw);
2389     }
2390     if (line != NULL)
2391 	*line = pi->vram_now;
2392 
2393     pi->ynow++;
2394     if (pi->ynow > ymax)
2395 	return (-2);
2396     return (pi->ynow);
2397 }
2398 
pic2_beta_saver_init(pi,line)2399 static int pic2_beta_saver_init(pi, line)
2400 struct pic2_info *pi;
2401 pixel **line;
2402 {
2403     pi->ynow = 0;
2404 
2405     *line = pi->vram_now;
2406     pi->next_line = pic2_beta_press_line;
2407     pic2_seek_file(pi, pi->next_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET);
2408     return (0);
2409 }
2410 
2411 /*
2412  * This function saves compressed data.
2413  */
pic2_write_data(pi,data,ptype,x_offset,y_offset,w,h,rmap,gmap,bmap,type,depth)2414 static void pic2_write_data(pi, data, ptype, x_offset, y_offset, w, h,
2415 			    rmap, gmap, bmap, type, depth)
2416 struct pic2_info *pi;
2417 byte *data;
2418 int ptype;
2419 int x_offset, y_offset;
2420 int w, h;
2421 byte *rmap, *gmap, *bmap;
2422 int type, depth;
2423 {
2424     int i, line;
2425     pixel *linep;
2426     short colbits;
2427 
2428     colbits = pi->header->depth / 3;
2429 
2430     line = pic2_save_block(pi, &linep, x_offset, y_offset, w, h,
2431 			   form_tab[type].id, 0xffffffff);
2432     while (line >= 0) {
2433 	byte r, g, b;
2434 	int pic_idx;
2435 
2436 	pic_idx = line * w * ((ptype == PIC24) ? 3 : 1);
2437 
2438 	for (i = 0; i < w; i++) {
2439 	    if (ptype != PIC24) {
2440 		r = rmap[data[pic_idx]];
2441 		g = gmap[data[pic_idx]];
2442 		b = bmap[data[pic_idx]];
2443 		pic_idx++;
2444 	    } else {
2445 		r = data[pic_idx++];
2446 		g = data[pic_idx++];
2447 		b = data[pic_idx++];
2448 	    }
2449 	    if (pi->writing_grey)
2450 		r = g = b = MONO(r, g, b);
2451 
2452 	    r = pic2_convert_color_bits(r, 8, colbits);
2453 	    g = pic2_convert_color_bits(g, 8, colbits);
2454 	    b = pic2_convert_color_bits(b, 8, colbits);
2455 
2456 	    linep[i] = ((pixel) r << (colbits * 2))
2457 		     | ((pixel) g <<  colbits     )
2458 		     | ((pixel) b                 );
2459 	}
2460 	line = pic2_next_line(pi, &linep);
2461 	WaitCursor();
2462     }
2463 }
2464 
2465 /*
2466  * This function compresses/extracts one line buffer.
2467  */
pic2_next_line(pi,line)2468 static int pic2_next_line(pi, line)
2469 struct pic2_info *pi;
2470 pixel **line;
2471 {
2472     int res;
2473 
2474     res = pi->next_line(pi, line);
2475     if (res == -2) {
2476 	if (pi->mode == PIC2_WRITE_MODE) {
2477 	    long new_pos;
2478 
2479 	    new_pos = pic2_tell_file(pi);
2480 	    pi->block->size = new_pos - pi->next_pos;
2481 	    pic2_seek_file(pi, pi->next_pos, SEEK_SET);
2482 	    pic2_write_block_header(pi);
2483 	    pi->next_pos = new_pos;
2484 	    if (DEBUG)
2485 		pic2_show_pic2_info(pi);
2486 	}
2487 	pic2_free_buffer(pi);
2488     }
2489     return (res);
2490 }
2491 
2492 /*
2493  * These functions find the pic2 image block.
2494  * pic2_next_block:
2495  *	moves the file pointer to the next image block.
2496  * pic2_find_block:
2497  *	finds the first image block and moves the file pointer there.
2498  */
pic2_next_block(pi)2499 static int pic2_next_block(pi)
2500 struct pic2_info *pi;
2501 {
2502     int i;
2503 
2504     if (pi->mode != PIC2_READ_MODE)
2505 	return (-1);
2506 
2507     /* go to block for read */
2508     pic2_seek_file(pi, pi->next_pos, SEEK_SET);
2509 
2510     /* read the head of block header */
2511     pic2_read_block_header1(pi);
2512 
2513     /* end block ? */
2514     if (pi->block->id[0] == 0)
2515 	return (0);
2516 
2517     /* set current block */
2518     pi->block_pos = pi->next_pos;
2519 
2520     /* set next block */
2521     pi->next_pos += pi->block->size;
2522 
2523    /* check block id */
2524     for (i = 0; i < n_form_tab; i++) {
2525 	if (xvbcmp(pi->block->id, form_tab[i].id, (size_t) 4) == 0)
2526 	    break;
2527     }
2528     if (i == n_form_tab)
2529 	return (2);
2530 
2531     /* read the rest of block header */
2532     pic2_read_block_header2(pi);
2533 
2534     if (pi->block->x_offset + pi->block->x_wid > pi->x_max)
2535 	pi->x_max = pi->block->x_offset + pi->block->x_wid;
2536 
2537     if (pi->block->y_offset + pi->block->y_wid > pi->y_max)
2538 	pi->y_max = pi->block->y_offset + pi->block->y_wid;
2539 
2540     if (DEBUG)
2541 	pic2_show_pic2_info(pi);
2542     return (1);
2543 }
2544 
pic2_find_block(pi)2545 static int pic2_find_block(pi)
2546 struct pic2_info *pi;
2547 {
2548     if (pi->mode != PIC2_READ_MODE)
2549 	return (-1);
2550 
2551     pi->next_pos = pi->header->size;
2552     return (pic2_next_block(pi));
2553 }
2554 
2555 /*
2556  * These functions load/save the pic2 image block.
2557  * pic2_load_block:
2558  *	initializes loader information with current block information.
2559  * pic2_save_block:
2560  *	initializes saver information.
2561  */
pic2_load_block(pi)2562 static int pic2_load_block(pi)
2563 struct pic2_info *pi;
2564 {
2565     int i;
2566 
2567     for (i = 0; i < n_form_tab; i++) {
2568 	if (xvbcmp(pi->block->id, form_tab[i].id, (size_t) 4) == 0)
2569 	    break;
2570     }
2571     if (i == n_form_tab)
2572 	return (2);
2573 
2574     pic2_alloc_buffer(pi);
2575     return (form_tab[i].loader_init(pi));
2576 }
2577 
pic2_save_block(pi,line,x,y,xw,yw,id,opaque)2578 static int pic2_save_block(pi, line, x, y, xw, yw, id, opaque)
2579 struct pic2_info *pi;
2580 pixel **line;
2581 int x, y, xw, yw;
2582 char *id;
2583 pixel opaque;
2584 {
2585     int i;
2586 
2587     for (i = 0; i < n_form_tab; i++) {
2588 	if (xvbcmp(id, form_tab[i].id, (size_t) 4) == 0)
2589 	    break;
2590     }
2591     if (i == n_form_tab)
2592 	return (2);
2593 
2594     strncpy(pi->block->id, id, 4);
2595     pi->block->x_wid = xw;
2596     pi->block->y_wid = yw;
2597     pi->block->x_offset = x;
2598     pi->block->y_offset = y;
2599     pi->block->reserve = 0;
2600 
2601     if (x < 0)
2602 	x = 0;
2603     if (y < 0)
2604 	y = 0;
2605     if (x + xw > pi->x_max)
2606 	pi->x_max = x + xw;
2607     if (y + yw > pi->y_max)
2608 	pi->y_max = y + yw;
2609 
2610     if (opaque != 0xffffffff) {
2611 	pi->block->flag = 1;
2612 	pi->block->opaque = opaque;
2613     } else {
2614 	pi->block->flag = 0;
2615 	pi->block->opaque = 0;
2616     }
2617     pic2_alloc_buffer(pi);
2618 
2619     return (form_tab[i].saver_init(pi, line));
2620 }
2621 
2622 /*
2623  * These functions set/get palettes.
2624  * pic2_read_palette:
2625  *	copy the palettes from pic2_info to PICINFO.
2626  * pic2_write_palette:
2627  *	copy the palettes from PICINFO to pic2_info.
2628  */
2629 #ifndef PIC2_IGNORE_UNUSED_FUNCTIONS
pic2_read_palette(pi,r,g,b)2630 static void pic2_read_palette(pi, r, g, b)
2631 struct pic2_info *pi;
2632 byte *r, *g, *b;
2633 {
2634     int i;
2635 
2636     if (pi->n_pal > 256)
2637 	pi->n_pal = 256;
2638 
2639     if (pi->pal_bits > 8)
2640 	pi->pal_bits = 8;
2641 
2642     for (i = 0; i < pi->n_pal; i++) {
2643 	*r++ =pic2_convert_color_bits(pi->pal[i][0] >> (8 - pi->pal_bits),
2644 				      pi->pal_bits, 8);
2645 	*g++ =pic2_convert_color_bits(pi->pal[i][1] >> (8 - pi->pal_bits),
2646 				      pi->pal_bits, 8);
2647 	*b++ =pic2_convert_color_bits(pi->pal[i][2] >> (8 - pi->pal_bits),
2648 				      pi->pal_bits, 8);
2649     }
2650 }
2651 
pic2_write_palette(pi,n_pal,pal_bits,r,g,b)2652 static void pic2_write_palette(pi, n_pal, pal_bits, r, g, b)
2653 struct pic2_info *pi;
2654 int n_pal, pal_bits;
2655 byte *r, *g, *b;
2656 {
2657     int i;
2658 
2659     if (n_pal > 256)
2660 	pi->n_pal = 256;
2661     else
2662 	pi->n_pal = n_pal;
2663 
2664     if (pal_bits > 8)
2665 	pi->pal_bits = 8;
2666     else
2667 	pi->pal_bits = pal_bits;
2668 
2669     for (i = 0; i < n_pal; i++) {
2670 	pi->pal[i][0] = pic2_convert_color_bits(*r++, 8, pal_bits)
2671 	    << (8 - pal_bits);
2672 	pi->pal[i][1] = pic2_convert_color_bits(*g++, 8, pal_bits)
2673 	    << (8 - pal_bits);
2674 	pi->pal[i][2] = pic2_convert_color_bits(*b++, 8, pal_bits)
2675 	    << (8 - pal_bits);
2676     }
2677 }
2678 #endif /* PIC2_IGNORE_UNUSED_FUNCTIONS */
2679 
2680 /*
2681  * These functions handle color bits.
2682  * pic2_convert_color_bits:
2683  *	converts color bits.
2684  * pic2_pad_color_bits:
2685  *	pads color bits.
2686  * pic2_reduce_color_bits:
2687  *	reduces color bits.
2688  * pic2_exchange_rg:
2689  *      exchanges red and green values.
2690  */
pic2_convert_color_bits(c,from,to)2691 static byte pic2_convert_color_bits(c, from, to)
2692 int c, from, to;
2693 {
2694     if (from == to)
2695 	return ((byte) c);
2696     else if (from < to)
2697 	return (pic2_pad_color_bits(c, from, to));
2698     else
2699 	return (pic2_reduce_color_bits(c, from, to));
2700 }
2701 
pic2_pad_color_bits(c,from,to)2702 static byte pic2_pad_color_bits(c, from, to)
2703 int c, from, to;
2704 {
2705     byte p = 0;
2706 
2707     do {
2708 	to -= from;
2709 	p |= pic2_shift_bits(c, to);
2710     } while (to >= 0);
2711     return (p);
2712 }
2713 
pic2_reduce_color_bits(c,from,to)2714 static byte pic2_reduce_color_bits(c, from, to)
2715 int c, from, to;
2716 {
2717     return ((byte) (c >> (from - to)));
2718 }
2719 
pic2_exchange_rg(p,colbits)2720 static pixel pic2_exchange_rg(p, colbits)
2721 pixel p;
2722 int colbits;
2723 {
2724     pixel rmask, gmask, bmask;
2725 
2726     rmask = (0xff >> (8 - colbits)) << (colbits * 2);
2727     gmask = (0xff >> (8 - colbits)) <<  colbits;
2728     bmask = (0xff >> (8 - colbits));
2729 
2730     p = ((p << colbits) & rmask)
2731       | ((p >> colbits) & gmask)
2732       | ( p             & bmask);
2733     return (p);
2734 }
2735 
2736 /*
2737  * This function handles work memory buffer.
2738  */
pic2_handle_para(pi,mode)2739 static void pic2_handle_para(pi, mode)
2740 struct pic2_info *pi;
2741 int mode;
2742 {
2743     static pixel *vram_prev, *vram_now, *vram_next;
2744     static short *flag_now, *flag_next;
2745     static short *flag2_now, *flag2_next, *flag2_next2;
2746 
2747     switch (mode) {
2748     case 0:
2749 	vram_prev = pi->vram_prev;
2750 	vram_now = pi->vram_now;
2751 	vram_next = pi->vram_next;
2752 	flag_now = pi->flag_now;
2753 	flag_next = pi->flag_next;
2754 	flag2_now = pi->flag2_now;
2755 	flag2_next = pi->flag2_next;
2756 	flag2_next2 = pi->flag2_next2;
2757 	pi->vram_prev += 4;
2758 	pi->vram_now += 4;
2759 	pi->vram_next += 4;
2760 	pi->flag_now += 4;
2761 	pi->flag_next += 4;
2762 	pi->flag2_now += 4;
2763 	pi->flag2_next += 4;
2764 	pi->flag2_next2 += 4;
2765 	break;
2766     case 1:
2767 	pi->vram_prev = vram_now;
2768 	pi->vram_now = vram_next;
2769 	pi->vram_next = vram_prev;
2770 	pi->flag_now = flag_next;
2771 	pi->flag_next = flag_now;
2772 	pi->flag2_now = flag2_next;
2773 	pi->flag2_next = flag2_next2;
2774 	pi->flag2_next2 = flag2_now;
2775 	break;
2776     }
2777 }
2778 
2779 /*
2780  * These functions alloc/free work memory.
2781  * pic2_alloc_buffer:
2782  *	alloc work memory buffer.
2783  * pic2_free_buffer:
2784  *	free work memory buffer.
2785  */
pic2_alloc_buffer(pi)2786 static int pic2_alloc_buffer(pi)
2787 struct pic2_info *pi;
2788 {
2789     int wid;
2790     byte *p;
2791 
2792     if (pi->buf != NULL)
2793 	return (-1);
2794 
2795     wid = pi->block->x_wid;
2796 
2797     p = pi->buf = (byte *) pic2_new((wid + 8) * sizeof(pixel) * 3   // GRR POSSIBLE OVERFLOW / FIXME
2798 				    + sizeof(pi->cache[0]) * 8 * 8 * 8
2799 				    + sizeof(pi->cache_pos[0]) * 8 * 8 * 8
2800 				    + sizeof(pi->mulu_tab[0]) * 16384
2801 				    + sizeof(pi->flag_now[0]) * ((wid+8) * 5),
2802 				    "pic2_alloc_buffer");
2803 
2804     pi->vram_prev = (pixel *) p;
2805     p += (wid + 8) * sizeof(pixel);
2806     pi->vram_now = (pixel *) p;
2807     p += (wid + 8) * sizeof(pixel);
2808     pi->vram_next = (pixel *) p;
2809     p += (wid + 8) * sizeof(pixel);
2810     pi->cache = (pixel (*)[PIC2_ARITH_CACHE]) p;
2811     p += sizeof(pi->cache[0]) * 8 * 8 * 8;
2812     pi->cache_pos = (unsigned short *) p;
2813     p += sizeof(pi->cache_pos[0]) * 8 * 8 * 8;
2814     pi->mulu_tab = (unsigned short *) p;
2815     p += sizeof(pi->mulu_tab[0]) * 16384;
2816     pi->flag_now = (short *) p;
2817     p += sizeof(pi->flag_now[0]) * (wid + 8);
2818     pi->flag_next = (short *) p;
2819     p += sizeof(pi->flag_next[0]) * (wid + 8);
2820     pi->flag2_now = (short *) p;
2821     p += sizeof(pi->flag2_now[0]) * (wid + 8);
2822     pi->flag2_next = (short *) p;
2823     p += sizeof(pi->flag2_next[0]) * (wid + 8);
2824     pi->flag2_next2 = (short *) p;
2825     p += sizeof(pi->flag2_next2[0]) * (wid + 8);
2826     return (0);
2827 }
2828 
pic2_free_buffer(pi)2829 static void pic2_free_buffer(pi)
2830 struct pic2_info *pi;
2831 {
2832     free(pi->buf);
2833     pi->buf = NULL;
2834 }
2835 
2836 /*
2837  * These functions handle the file pointer.
2838  * pic2_seek_file:
2839  *	moves the file pointer.
2840  * pic2_tell_file:
2841  *	tells the location of the file pointer.
2842  */
pic2_seek_file(pi,offset,whence)2843 static long pic2_seek_file(pi, offset, whence)
2844 struct pic2_info *pi;
2845 long offset;
2846 int whence;
2847 {
2848     long n;
2849 
2850     n = fseek(pi->fp, offset, whence);
2851     if (n < 0)
2852 	pic2_file_error(pi, PIC2_CORRUPT);
2853 
2854     return (n);
2855 }
2856 
pic2_tell_file(pi)2857 static long pic2_tell_file(pi)
2858 struct pic2_info *pi;
2859 {
2860     return (ftell(pi->fp));
2861 }
2862 
2863 /*
2864  * These functions handle file.
2865  * pic2_read_file:
2866  *	reads data from the file.
2867  * pic2_read_long:
2868  *	reads long word data from the file and converts to internal expression.
2869  * pic2_read_short:
2870  *	reads word data from the file and converts to internal expression.
2871  * pic2_read_char:
2872  *	reads byte data from the file.
2873  * pic2_write_file:
2874  *	writes data to the file.
2875  * pic2_write_long:
2876  *	converts long word data to common expression and writes to the file.
2877  * pic2_write_short:
2878  *	converts word data to common expression and writes to the file.
2879  * pic2_write_char:
2880  *	writes byte data to the file.
2881  */
pic2_read_file(pi,buf,size)2882 static int pic2_read_file(pi, buf, size)
2883 struct pic2_info *pi;
2884 void *buf;
2885 size_t size;
2886 {
2887     if (fread(buf, (size_t) 1, size, pi->fp) < size)
2888 	pic2_file_error(pi, PIC2_CORRUPT);
2889     return (0);
2890 }
2891 
pic2_read_long(pi)2892 static long pic2_read_long(pi)
2893 struct pic2_info *pi;
2894 {
2895     byte buf[4];
2896 
2897     if (fread(buf, (size_t) 4, (size_t) 1, pi->fp) < 1)
2898 	pic2_file_error(pi, PIC2_CORRUPT);
2899     return (pic2_cextolong(buf));
2900 }
2901 
pic2_read_short(pi)2902 static short pic2_read_short(pi)
2903 struct pic2_info *pi;
2904 {
2905     byte buf[2];
2906 
2907     if (fread(buf, (size_t) 2, (size_t) 1, pi->fp) < 1)
2908 	pic2_file_error(pi, PIC2_CORRUPT);
2909     return (pic2_cextoshort(buf));
2910 }
2911 
pic2_read_char(pi)2912 static char pic2_read_char(pi)
2913 struct pic2_info *pi;
2914 {
2915     int c;
2916 
2917     if ((c = fgetc(pi->fp)) == EOF)
2918 	pic2_file_error(pi, PIC2_CORRUPT);
2919     return ((char) c);
2920 }
2921 
pic2_write_file(pi,buf,size)2922 static int pic2_write_file(pi, buf, size)
2923 struct pic2_info *pi;
2924 void *buf;
2925 size_t size;
2926 {
2927     if (fwrite(buf, (size_t) 1, size, pi->fp) < size)
2928 	pic2_error(pi, PIC2_WRITE);
2929     return (0);
2930 }
2931 
pic2_write_long(pi,n)2932 static int pic2_write_long(pi, n)
2933 struct pic2_info *pi;
2934 long n;
2935 {
2936     byte buf[4];
2937 
2938     pic2_longtocex(buf, n);
2939     if (fwrite(buf, (size_t) 4, (size_t) 1, pi->fp) < 1)
2940 	pic2_error(pi, PIC2_WRITE);
2941     return (0);
2942 }
2943 
pic2_write_short(pi,n)2944 static int pic2_write_short(pi, n)
2945 struct pic2_info *pi;
2946 int n;
2947 {
2948     byte buf[2];
2949 
2950     pic2_shorttocex(buf, n);
2951     if (fwrite(buf, (size_t) 2, (size_t) 1, pi->fp) < 1)
2952 	pic2_error(pi, PIC2_WRITE);
2953     return (0);
2954 }
2955 
pic2_write_char(pi,c)2956 static int pic2_write_char(pi, c)
2957 struct pic2_info *pi;
2958 int c;
2959 {
2960     if (fputc(c, pi->fp) == EOF)
2961 	pic2_error(pi, PIC2_WRITE);
2962     return (0);
2963 }
2964 
2965 /*
2966  * These functions access the bit stream.
2967  * pic2_read_bits:
2968  *	reads the specified bits from the file.
2969  * pic2_write_bits:
2970  *	writes the specified bits to the file.
2971  * pic2_flush_bits:
2972  *	flushes bit buffer to the file.
2973  */
pic2_read_bits(pi,bits)2974 static unsigned long pic2_read_bits(pi, bits)
2975 struct pic2_info *pi;
2976 int bits;
2977 {
2978     unsigned long r = 0;
2979 
2980     while (bits > 0) {
2981 	while (pi->bs.rest > 0 && bits > 0) {
2982 	    r = (r << 1) | (pi->bs.cur & 0x80 ? 1 : 0);
2983 	    pi->bs.cur <<= 1;
2984 	    pi->bs.rest--;
2985 	    bits--;
2986 	}
2987 	if (bits > 0) {
2988 	    int c;
2989 	    if ((c = fgetc(pi->fp)) == EOF)
2990 		pic2_file_error(pi, PIC2_CORRUPT);
2991 	    pi->bs.cur  = (byte) c;
2992 	    pi->bs.rest = 8;
2993 	}
2994     }
2995     return r;
2996 }
2997 
pic2_write_bits(pi,dat,bits)2998 static void pic2_write_bits(pi, dat, bits)
2999 struct pic2_info *pi;
3000 unsigned long dat;
3001 int bits;
3002 {
3003     unsigned long dat_mask = 1 << (bits - 1);
3004 
3005     while (bits > 0) {
3006 	while (pi->bs.rest < 8 && bits > 0) {
3007 	    pi->bs.cur <<= 1;
3008 	    if (dat & dat_mask)
3009 		pi->bs.cur |= 1;
3010 	    pi->bs.rest++;
3011 	    bits--;
3012 	    dat_mask >>= 1;
3013 	}
3014 	if (pi->bs.rest >= 8) {
3015 	    if ((fputc((int) pi->bs.cur, pi->fp)) == EOF)
3016 		pic2_error(pi, PIC2_WRITE);
3017 	    pi->bs.cur  = 0;
3018 	    pi->bs.rest = 0;
3019 	}
3020     }
3021 }
3022 
pic2_flush_bits(pi)3023 static void pic2_flush_bits(pi)
3024 struct pic2_info *pi;
3025 {
3026     if (pi->bs.rest < 8) {
3027 	pi->bs.cur <<= 8 - pi->bs.rest;
3028 	if (fputc((int) pi->bs.cur, pi->fp) == EOF)
3029 		pic2_error(pi, PIC2_WRITE);
3030 	pi->bs.cur  = 0;
3031 	pi->bs.rest = 0;
3032     }
3033 }
3034 
3035 /*
3036  * These functions initialize or clean up structures.
3037  * pic2_init_info:
3038  *	initializes a pic2_info structure.
3039  * pic2_cleanup_pic2_info:
3040  *	cleans up a pic_info structure.
3041  * pic2_cleanup_pinfo:
3042  *	cleans up a PICINFO structure.
3043  */
pic2_init_info(pi)3044 static void pic2_init_info(pi)
3045 struct pic2_info *pi;
3046 {
3047     xvbzero((char *) pi, sizeof(struct pic2_info));
3048     pi->header = pic2_new(sizeof(struct pic2_header), "pic2_init_info#1");
3049     pi->block = pic2_new(sizeof(struct pic2_block), "pic2_init_info#2");
3050 }
3051 
pic2_cleanup_pic2_info(pi,writing)3052 static void pic2_cleanup_pic2_info(pi, writing)
3053 struct pic2_info *pi;
3054 int writing;
3055 {
3056     if (!writing && pi->fp)
3057 	fclose(pi->fp);
3058     if (pi->header)
3059 	free(pi->header);
3060     if (pi->block)
3061 	free(pi->block);
3062     pi->fp = NULL;
3063     pi->header = NULL;
3064     pi->block = NULL;
3065     pi->comment = NULL;
3066 }
3067 
pic2_cleanup_pinfo(pinfo)3068 static void pic2_cleanup_pinfo(pinfo)
3069 PICINFO *pinfo;
3070 {
3071     if (pinfo->pic){
3072 	free(pinfo->pic);
3073 	pinfo->pic = NULL;
3074     }
3075     if (pinfo->comment){
3076 	free(pinfo->comment);
3077 	pinfo->comment = NULL;
3078     }
3079 }
3080 
3081 /*
3082  * Error Handlers.
3083  * pic2_memory_error:
3084  *	shows an error message and terminates.
3085  * pic2_error:
3086  *	shows a non-file error message and jumps to the entry for errors.
3087  * pic2_file_error:
3088  *	shows a file error message and jumps to the entry for errors.
3089  */
pic2_memory_error(scm,fn)3090 static void pic2_memory_error(scm, fn)
3091 char *scm, *fn;
3092 {
3093     char buf[128];
3094     sprintf(buf, "%s: can't allocate memory. (%s)", scm, fn);
3095     FatalError(buf);
3096 }
3097 
pic2_error(pi,mn)3098 static void pic2_error(pi, mn)
3099 struct pic2_info *pi;
3100 int mn;
3101 {
3102     SetISTR(ISTR_WARNING, "%s", pic2_msgs[mn]);
3103     longjmp(pi->jmp, 1);
3104 }
3105 
pic2_file_error(pi,mn)3106 static void pic2_file_error(pi, mn)
3107     struct pic2_info *pi;
3108     int mn;
3109 {
3110     if (feof(pi->fp))
3111 	SetISTR(ISTR_WARNING, "%s (end of file)", pic2_msgs[mn]);
3112     else
3113 	SetISTR(ISTR_WARNING, "%s (%s)", pic2_msgs[mn], ERRSTR(errno));
3114     longjmp(pi->jmp, 1);
3115 }
3116 
pic2_show_pic2_info(pi)3117 static void pic2_show_pic2_info(pi)
3118     struct pic2_info *pi;
3119 {
3120     fprintf(stderr, "file size: %ld.\n", pi->fsize);
3121     fprintf(stderr, "full image size: %dx%d\n", pi->x_max, pi->y_max);
3122     fprintf(stderr, "number of palettes: %d\n", pi->n_pal);
3123     fprintf(stderr, "depth of palettes: %d\n", pi->pal_bits);
3124     fprintf(stderr, "current block position: %ld\n", pi->block_pos);
3125     fprintf(stderr, "next block position: %ld\n\n", pi->next_pos);
3126 
3127     fprintf(stderr, "header flag: %x\n", pi->header->flag);
3128     fprintf(stderr, "header size: %ld\n", pi->header->size);
3129     fprintf(stderr, "x_aspect: %d, y_aspect: %d\n",
3130 	    pi->header->x_aspect, pi->header->y_aspect);
3131     fprintf(stderr, "number of color bits: %d\n\n", pi->header->depth);
3132 
3133     fprintf(stderr, "image block id: %s\n", pi->block->id);
3134     fprintf(stderr, "image block size: %ld\n", pi->block->size);
3135     fprintf(stderr, "block flag: %x\n", pi->block->flag);
3136 
3137     fprintf(stderr, "block image size: %dx%d\n",
3138 	    pi->block->x_wid, pi->block->y_wid);
3139     fprintf(stderr, "x_offset: %d\n", pi->block->x_offset);
3140     fprintf(stderr, "y_offset: %d\n", pi->block->y_offset);
3141     fprintf(stderr, "opaque color: %lx\n\n", pi->block->opaque);
3142 }
3143 
3144 /*
3145  * This function is similar to strncpy.
3146  * But this pads with whitespace after the null character.
3147  */
pic2_strncpy(dest,src,n)3148 static char *pic2_strncpy(dest, src, n)
3149 char *dest, *src;
3150 size_t n;
3151 {
3152     char *r;
3153 
3154     r = dest;
3155     while (n--)
3156 	if ((src != NULL) && (*src != '\r') && (*src != '\n') && *src)
3157 	    *dest++ = *src++;
3158 	else
3159 	    *dest++ = ' ';
3160     return (r);
3161 }
3162 
3163 /*
3164  * These functions create a memory block.
3165  */
pic2_malloc(size,fn)3166 static void *pic2_malloc(size, fn)
3167 size_t size;
3168 char *fn;
3169 {
3170     void *p;
3171 
3172     p = (void *) malloc(size);
3173     if (p == NULL)
3174 	pic2_memory_error("malloc", fn);
3175     return (p);
3176 }
3177 
pic2_new(size,fn)3178 static void *pic2_new(size, fn)
3179 size_t size;
3180 char *fn;
3181 {
3182     void *p;
3183 
3184     p = (void *) pic2_malloc(size, fn);
3185     xvbzero((char *) p, size);
3186     return (p);
3187 }
3188 
3189 
3190 
3191 
3192 /**** Stuff for PIC2Dialog box ****/
3193 
3194 #define TWIDE    320
3195 #define THIGH	 178
3196 #define T_NBUTTS 2
3197 #define T_BOK    0
3198 #define T_BCANC  1
3199 #define BUTTH    24
3200 
3201 static void drawTD    PARM((int,int,int,int));
3202 static void clickTD   PARM((int,int));
3203 static void doCmd     PARM((int));
3204 static void writePIC2 PARM((void));
3205 
3206 /* local variables */
3207 static FILE  *fp;
3208 static char  *filename;
3209 static int   colorType;
3210 static int   append;
3211 static int   x_offset;
3212 static int   y_offset;
3213 static BUTT  tbut[T_NBUTTS];
3214 static RBUTT *typeRB;
3215 static RBUTT *depthRB;
3216 
3217 
3218 
3219 /***************************************************/
CreatePIC2W()3220 void CreatePIC2W()
3221 {
3222     int	     y;
3223 
3224     pic2W = CreateWindow("xv pic2", "XVpic2", NULL,
3225 			TWIDE, THIGH, infofg, infobg, 0);
3226     if (!pic2W)
3227 	FatalError("can't create pic2 window!");
3228 
3229     XSelectInput(theDisp, pic2W,
3230 		 ExposureMask | ButtonPressMask | KeyPressMask);
3231 
3232     BTCreate(&tbut[T_BOK], pic2W, TWIDE-140-1, THIGH-10-BUTTH-1, 60, BUTTH,
3233 	     "Ok", infofg, infobg, hicol, locol);
3234 
3235     BTCreate(&tbut[T_BCANC], pic2W, TWIDE-70-1, THIGH-10-BUTTH-1, 60, BUTTH,
3236 	     "Cancel", infofg, infobg, hicol, locol);
3237 
3238     y = 55;
3239     typeRB = RBCreate(NULL, pic2W, 36, y,          "P2SS",
3240 		      infofg, infobg,hicol,locol);
3241     RBCreate(typeRB, pic2W, 36, y+18,              "P2SF",
3242 	     infofg, infobg,hicol,locol);
3243     RBCreate(typeRB, pic2W, 36, y+36,              "P2BM",
3244 	     infofg, infobg, hicol, locol);
3245     RBCreate(typeRB, pic2W, 36, y+54,              "P2BI",
3246 	     infofg, infobg, hicol, locol);
3247 
3248     depthRB = RBCreate(NULL, pic2W, TWIDE/2-16, y, "  3bit",
3249 		       infofg, infobg,hicol,locol);
3250     RBCreate(depthRB, pic2W, TWIDE/2-16, y+18,     "  6bit",
3251 	     infofg, infobg,hicol,locol);
3252     RBCreate(depthRB, pic2W, TWIDE/2-16, y+36,     "  9bit",
3253 	     infofg, infobg, hicol, locol);
3254     RBCreate(depthRB, pic2W, TWIDE/2-16, y+54,     "12bit",
3255 	     infofg, infobg, hicol, locol);
3256     RBCreate(depthRB, pic2W, TWIDE/4*3-16, y,      "15bit",
3257 	     infofg, infobg, hicol, locol);
3258     RBCreate(depthRB, pic2W, TWIDE/4*3-16, y+18,   "18bit",
3259 	     infofg, infobg, hicol, locol);
3260     RBCreate(depthRB, pic2W, TWIDE/4*3-16, y+36,   "21bit",
3261 	     infofg, infobg, hicol, locol);
3262     RBCreate(depthRB, pic2W, TWIDE/4*3-16, y+54,   "24bit",
3263 	     infofg, infobg, hicol, locol);
3264 
3265     XMapSubwindows(theDisp, pic2W);
3266 }
3267 
3268 
3269 /***************************************************/
PIC2Dialog(vis)3270 void PIC2Dialog(vis)
3271 int vis;
3272 {
3273     if (vis) {
3274 	CenterMapWindow(pic2W, tbut[T_BOK].x + tbut[T_BOK].w/2,
3275 			tbut[T_BOK].y + tbut[T_BOK].h/2, TWIDE, THIGH);
3276     }
3277     else     XUnmapWindow(theDisp, pic2W);
3278     pic2Up = vis;
3279 }
3280 
3281 
3282 /***************************************************/
PIC2CheckEvent(xev)3283 int PIC2CheckEvent(xev)
3284 XEvent *xev;
3285 {
3286     /* check event to see if it's for one of our subwindows.  If it is,
3287        deal accordingly and return '1'.  Otherwise, return '0'. */
3288 
3289     int rv;
3290     rv = 1;
3291 
3292     if (!pic2Up)
3293 	return (0);
3294 
3295     if (xev->type == Expose) {
3296 	int x,y,w,h;
3297 	XExposeEvent *e = (XExposeEvent *) xev;
3298 	x = e->x;  y = e->y;  w = e->width;  h = e->height;
3299 
3300 	if (e->window == pic2W)       drawTD(x, y, w, h);
3301 	else rv = 0;
3302     }
3303 
3304     else if (xev->type == ButtonPress) {
3305 	XButtonEvent *e = (XButtonEvent *) xev;
3306 	int x,y;
3307 	x = e->x;  y = e->y;
3308 
3309 	if (e->button == Button1) {
3310 	    if      (e->window == pic2W)     clickTD(x,y);
3311 	    else rv = 0;
3312 	}  /* button1 */
3313 	else rv = 0;
3314     }  /* button press */
3315 
3316 
3317     else if (xev->type == KeyPress) {
3318 	XKeyEvent *e = (XKeyEvent *) xev;
3319 	char buf[128];  KeySym ks;  XComposeStatus status;
3320 	int stlen;
3321 
3322 	stlen = XLookupString(e,buf,128,&ks,&status);
3323 	buf[stlen] = '\0';
3324 
3325 	if (e->window == pic2W) {
3326 	    if (stlen) {
3327 		if (buf[0] == '\r' || buf[0] == '\n') { /* enter */
3328 		    FakeButtonPress(&tbut[T_BOK]);
3329 		}
3330 		else if (buf[0] == '\033') {            /* ESC */
3331 		    FakeButtonPress(&tbut[T_BCANC]);
3332 		}
3333 	    }
3334 	}
3335 	else rv = 0;
3336     }
3337     else rv = 0;
3338 
3339     if (rv == 0 && (xev->type == ButtonPress || xev->type == KeyPress)) {
3340 	XBell(theDisp, 50);
3341 	rv = 1;   /* eat it */
3342     }
3343 
3344     return (rv);
3345 }
3346 
3347 
3348 /***************************************************/
PIC2SaveParams(fname,col)3349 int PIC2SaveParams(fname, col)
3350 char *fname;
3351 int col;
3352 {
3353     filename = fname;
3354     colorType = col;
3355 
3356     /* see if we can open the output file before proceeding */
3357     fp = pic2_OpenOutFile(filename, &append);
3358     if (!fp)
3359 	return (-1);
3360 
3361     RBSetActive(typeRB,0,1);
3362     RBSetActive(typeRB,1,1);
3363     RBSetActive(typeRB,2,1);
3364     RBSetActive(typeRB,3,1);
3365     RBSelect(typeRB,0);
3366 
3367 
3368     if (append) {
3369 	struct pic2_info pic2;
3370 
3371 	pic2_init_info(&pic2);
3372 	pic2.fp = fp;
3373 	pic2_read_header(&pic2);
3374 
3375 	RBSetActive(depthRB,0,0);
3376 	RBSetActive(depthRB,1,0);
3377 	RBSetActive(depthRB,2,0);
3378 	RBSetActive(depthRB,3,0);
3379 	RBSetActive(depthRB,4,0);
3380 	RBSetActive(depthRB,5,0);
3381 	RBSetActive(depthRB,6,0);
3382 	RBSetActive(depthRB,7,0);
3383 
3384 	switch (pic2.header->depth) {
3385 	case  3:
3386 	    RBSetActive(depthRB,0,1);
3387 	    RBSelect(depthRB,0);
3388 	    RBSetActive(typeRB,3,0);
3389 	    break;
3390 	case  6:
3391 	    RBSetActive(depthRB,1,1);
3392 	    RBSelect(depthRB,1);
3393 	    RBSetActive(typeRB,3,0);
3394 	    break;
3395 	case  9:
3396 	    RBSetActive(depthRB,2,1);
3397 	    RBSelect(depthRB,2);
3398 	    break;
3399 	case 12:
3400 	    RBSetActive(depthRB,3,1);
3401 	    RBSelect(depthRB,3);
3402 	    break;
3403 	case 15:
3404 	    RBSetActive(depthRB,4,1);
3405 	    RBSelect(depthRB,4);
3406 	    break;
3407 	case 18:
3408 	    RBSetActive(depthRB,5,1);
3409 	    RBSelect(depthRB,5);
3410 	    RBSetActive(typeRB,3,0);
3411 	    break;
3412 	case 21:
3413 	    RBSetActive(depthRB,6,1);
3414 	    RBSelect(depthRB,6);
3415 	    RBSetActive(typeRB,3,0);
3416 	    break;
3417 	case 24:
3418 	    RBSetActive(depthRB,7,1);
3419 	    RBSelect(depthRB,7);
3420 	    RBSetActive(typeRB,3,0);
3421 	    break;
3422 	default: {
3423 	    char str[512];
3424 	    sprintf(str, "unsupported PIC2 file '%s'.", filename);
3425 	    ErrPopUp(str, "\nBummer");
3426 	    CloseOutFile(fp, filename, 0);
3427 	    fp = OpenOutFile(fname);
3428 	    if (!fp)
3429 		return (-1);
3430 	    break;
3431 	}
3432 	}
3433 	pic2_seek_file(&pic2, 0, SEEK_SET);
3434 	pic2_cleanup_pic2_info(&pic2, 1);
3435     } else {
3436 	RBSetActive(depthRB,0,1);
3437 	RBSetActive(depthRB,1,1);
3438 	RBSetActive(depthRB,2,1);
3439 	RBSetActive(depthRB,3,1);
3440 	RBSetActive(depthRB,4,1);
3441 	RBSetActive(depthRB,5,1);
3442 	RBSetActive(depthRB,6,1);
3443 	RBSetActive(depthRB,7,1);
3444 	RBSelect(depthRB,7);
3445 	RBSetActive(typeRB,3,0);
3446     }
3447     return (0);
3448 }
3449 
3450 
3451 /***************************************************/
drawTD(x,y,w,h)3452 static void drawTD(x,y,w,h)
3453 int x,y,w,h;
3454 {
3455     char *title  = "Save PIC2 file...";
3456     int  i;
3457     XRectangle xr;
3458 
3459     xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
3460     XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
3461 
3462     XSetForeground(theDisp, theGC, infofg);
3463     XSetBackground(theDisp, theGC, infobg);
3464 
3465     for (i = 0; i < T_NBUTTS; i++)
3466 	BTRedraw(&tbut[i]);
3467 
3468     ULineString(pic2W, typeRB->x-16, typeRB->y-3-DESCENT,   "FormatType");
3469     ULineString(pic2W, depthRB->x-16, depthRB->y-3-DESCENT, "ColorDepth");
3470     RBRedraw(typeRB, -1);
3471     RBRedraw(depthRB, -1);
3472 
3473     DrawString(pic2W, 20, 29, title);
3474 
3475     XSetClipMask(theDisp, theGC, None);
3476 }
3477 
clickTD(x,y)3478 static void clickTD(x,y)
3479 int x,y;
3480 {
3481     int i;
3482     BUTT *bp;
3483 
3484     /* check BUTTs */
3485 
3486     /* check the RBUTTS first, since they don't DO anything */
3487     if ((i = RBClick(typeRB, x,y)) >= 0) {
3488 	(void) RBTrack(typeRB, i);
3489 	return;
3490     } else if ((i = RBClick(depthRB, x,y)) >= 0) {
3491 	(void) RBTrack(depthRB, i);
3492 	if ((2 <= i) && (i <= 4))
3493 	    RBSetActive(typeRB,3,1);
3494 	else {
3495 	    RBSetActive(typeRB,3,0);
3496 	    if (RBWhich(typeRB) == 3)
3497 		RBSelect(typeRB,0);
3498 	return;
3499 	}
3500     }
3501     for (i = 0; i < T_NBUTTS; i++) {
3502 	bp = &tbut[i];
3503 	if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h))
3504 	    break;
3505     }
3506     if (i < T_NBUTTS)  /* found one */
3507 	if (BTTrack(bp))
3508 	    doCmd(i);
3509 }
3510 
3511 
3512 
3513 /***************************************************/
doCmd(cmd)3514 static void doCmd(cmd)
3515 int cmd;
3516 {
3517     switch (cmd) {
3518     case T_BOK: {
3519 	char              *fullname;
3520 	char               buf[64], *x_offsetp, *y_offsetp;
3521 	static const char *labels[] = { "\nOk", "\033Cancel" };
3522         XEvent             event;
3523 	int                i;
3524 
3525 	strcpy(buf, "0,0");
3526 	i = GetStrPopUp("Enter offset (x,y):", labels, 2, buf, 64,
3527 			"01234567890,", 1);
3528 
3529 	if (i)
3530 	    return;
3531 	if (strlen(buf)==0)
3532 	    return;
3533 
3534 	x_offsetp = buf;
3535 	y_offsetp = index(buf, ',');
3536 	if (!y_offsetp)
3537 	    return;
3538 	*(y_offsetp++) = '\0';
3539 	if ((*x_offsetp == '\0') || (*y_offsetp == '\0'))
3540 	    return;
3541 	x_offset = atoi(x_offsetp);
3542 	y_offset = atoi(y_offsetp);
3543 
3544         XNextEvent(theDisp, &event);
3545 	HandleEvent(&event, &i);
3546 
3547 	writePIC2();
3548 	PIC2Dialog(0);
3549 
3550 	fullname = GetDirFullName();
3551 	if (!ISPIPE(fullname[0])) {
3552 	    XVCreatedFile(fullname);
3553 	    StickInCtrlList(0);
3554 	}
3555     }
3556 	break;
3557     case T_BCANC:
3558 	pic2_KillNullFile(fp);
3559 	PIC2Dialog(0);
3560 	break;
3561     default:
3562 	break;
3563     }
3564 }
3565 
3566 
3567 /*******************************************/
writePIC2()3568 static void writePIC2()
3569 {
3570     int   w, h, nc, rv, type, depth, ptype, pfree;
3571     byte *inpix, *rmap, *gmap, *bmap;
3572 
3573 
3574     WaitCursor();
3575     inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap);
3576 
3577     if (colorType == F_REDUCED)
3578 	colorType = F_FULLCOLOR;
3579 
3580     switch (RBWhich(typeRB)) {
3581     case 0: type = P2SS;  break;
3582     case 1: type = P2SF;  break;
3583     case 2: type = P2BM;  break;
3584     case 3: type = P2BI;  break;
3585     default: type = P2SS; break;
3586     }
3587     switch (RBWhich(depthRB)) {
3588     case 0: depth =  3;  break;
3589     case 1: depth =  6;  break;
3590     case 2: depth =  9;  break;
3591     case 3: depth = 12;  break;
3592     case 4: depth = 15;  break;
3593     case 5: depth = 18;  break;
3594     case 6: depth = 21;  break;
3595     case 7: depth = 24;  break;
3596     default: depth = 24; break;
3597     }
3598     rv = WritePIC2(fp, inpix, ptype, w, h,
3599 		   rmap, gmap, bmap, nc, colorType, filename,
3600 		   type, depth, x_offset, y_offset, append, picComments);
3601 
3602     if (CloseOutFile(fp, filename, rv) == 0)
3603 	DirBox(0);
3604 
3605     if (pfree)
3606 	free(inpix);
3607 }
3608 #endif /* HAVE_PIC2 */
3609