| int unpack_image(unsigned char *in, unsigned char *out, int width, long numcodes, size_t booga); | |
| void get_huffman_dictionary(void); | |
| static short mask[16] = { | |
| 0x0000, 0x0001, 0x0003, 0x0007, | |
| 0x000f, 0x001f, 0x003f, 0x007f, | |
| 0x00ff, 0x01ff, 0x03ff, 0x07ff, | |
| 0x0fff, 0x1fff, 0x3fff, 0x7fff | |
| }; | |
| typedef struct image_s { | |
| short width; | |
| short height; | |
| short colours; | |
| long pixels; | |
| unsigned char *image; | |
| unsigned char (*colourmap)[3]; | |
| } image_t; | |
| typedef struct compress_s { | |
| short next_code; | |
| short slen; | |
| short sptr; | |
| short tlen; | |
| short tptr; | |
| } compress_t; | |
| typedef struct nlist_s { | |
| struct nlist *next; | |
| short prefix; | |
| short pixel; | |
| short code; | |
| } nlist_t; | |
| typedef struct header_s { | |
| unsigned char part; | |
| unsigned char flags; | |
| unsigned short unknown1; | |
| unsigned short images; | |
| unsigned short unknown2; | |
| unsigned char dir_size; | |
| unsigned char unknown3; | |
| unsigned short checksum; | |
| unsigned short unknown4; | |
| unsigned short version; | |
| } header_t; | |
| typedef unsigned char color_t[3]; | |
| typedef struct colormap_s { | |
| unsigned char num_colors; | |
| color_t table[1]; | |
| } colormap_t; | |
| typedef struct pdirectory_s { | |
| short image_number; | |
| short image_width; | |
| short image_height; | |
| short image_flags; | |
| long image_data_addr; | |
| long image_cm_addr; | |
| short huffman_dict_addr; | |
| } pdirectory_t; | |
| static colormap_t *get_color_table(FILE *fp, pdirectory_t *directory); | |
| static void *get_image (FILE *, pdirectory_t *); | |
| static void decompress_image (FILE *, image_t *); | |
| static short read_code (FILE *, compress_t *); | |
| static header_t picfile_header; | |
| static int max_pic_index; | |
| static int *pic_index; | |
| static pdirectory_t *picture_directory = NULL; | |
| static short code_table[CODE_TABLE_SIZE][2]; | |
| static unsigned char buffer[CODE_TABLE_SIZE]; | |
| static unsigned char code_buffer[CODE_TABLE_SIZE]; | |
| static signed short *huffman_dictionary = NULL; | |
| static FILE *picfile; | |
| static unsigned char read_byte (FILE *fp) | |
| static unsigned char read_byte (fp) | |
| FILE *fp; | |
| { | |
| int c; | |
| if ((c = fgetc (fp)) == EOF) { | |
| perror ("fgetc"); | |
| exit (EXIT_FAILURE); | |
| } | |
| return ((unsigned char) c); | |
| }/* read_byte */ | |
| static unsigned short read_word (FILE *fp) | |
| static unsigned short read_word (fp) | |
| FILE *fp; | |
| { | |
| unsigned short w; | |
| w = (unsigned short) read_byte (fp) << 8; | |
| w += (unsigned short) read_byte (fp) ; | |
| return (w); | |
| }/* read_word */ | |
| int read_picture_data (void) | |
| int read_picture_data () | |
| { | |
| int i; | |
| char linebuf[80]; | |
| FILE *fp; | |
| long dir_pos; | |
| if ((fp = fopen ("CPIC.DATA", "rb")) == NULL) { | |
| fatal ("Couldn't open picture file"); | |
| } | |
| picfile_header.part = read_byte (fp); | |
| picfile_header.flags = read_byte (fp); | |
| picfile_header.unknown1 = read_word (fp); | |
| picfile_header.images = read_word (fp); | |
| picfile_header.unknown2 = read_word (fp); | |
| picfile_header.dir_size = read_byte (fp); | |
| picfile_header.unknown3 = read_byte (fp); | |
| picfile_header.checksum = read_word (fp); | |
| picfile_header.unknown4 = read_word (fp); | |
| picfile_header.version = read_word (fp); | |
| sprintf (linebuf, "Total number of images = %d", (int) picfile_header.images); | |
| output_string(linebuf); | |
| new_line(); | |
| if ((picture_directory = (pdirectory_t *) NewPtr (picfile_header.images * sizeof (pdirectory_t))) == NULL) { | |
| fatal("Insufficient memory\n"); | |
| } | |
| dir_pos = ftell(fp); | |
| max_pic_index = 0; | |
| for (i = 0; (unsigned int) i < picfile_header.images; i++) { | |
| picture_directory[i].image_number = read_word (fp); | |
| if (picture_directory[i].image_number > max_pic_index) { | |
| max_pic_index = picture_directory[i].image_number; | |
| } | |
| picture_directory[i].image_width = read_word (fp); | |
| picture_directory[i].image_height = read_word (fp); | |
| picture_directory[i].image_flags = read_word (fp); | |
| picture_directory[i].image_data_addr = (unsigned long) read_byte (fp) << 16; | |
| picture_directory[i].image_data_addr += (unsigned long) read_byte (fp) << 8; | |
| picture_directory[i].image_data_addr += (unsigned long) read_byte (fp); | |
| if (picfile_header.dir_size >= 14) { | |
| picture_directory[i].image_cm_addr = (unsigned long) read_byte (fp) << 16; | |
| picture_directory[i].image_cm_addr += (unsigned long) read_byte (fp) << 8; | |
| picture_directory[i].image_cm_addr += (unsigned long) read_byte (fp); | |
| } else { | |
| picture_directory[i].image_cm_addr = 0; | |
| /* (void) read_byte (fp); */ | |
| } | |
| if (picfile_header.dir_size >= 16) { | |
| picture_directory[i].huffman_dict_addr = read_word(fp); | |
| } | |
| fseek(fp,dir_pos += picfile_header.dir_size,SEEK_SET); | |
| } | |
| picfile = fp; | |
| if (picfile_header.flags & HUFFMAN_ONEDICT) | |
| get_huffman_dictionary(); | |
| pic_index = (void *)NewPtr((max_pic_index + 1) * sizeof(int)); | |
| memset(pic_index, 0xFF, (max_pic_index + 1) * sizeof(int)); | |
| for (i = 0; (unsigned int) i < picfile_header.images; i++) { | |
| pic_index[picture_directory[i].image_number] = i; | |
| } | |
| return (0); | |
| }/* read_picture_data */ | |
| void get_huffman_dictionary() | |
| { | |
| unsigned long fpos; | |
| int maxentry, curentry; | |
| short entry; | |
| short *entryptr; | |
| fpos = ftell(picfile); | |
| maxentry = 1; | |
| curentry = 0; | |
| while (curentry++ <= maxentry) { | |
| entry = (signed char)read_byte(picfile); | |
| if (entry > 0) { | |
| maxentry = MAX(maxentry,entry + entry + 1); | |
| } | |
| } | |
| fseek(picfile, fpos, SEEK_SET); | |
| if (huffman_dictionary) | |
| DisposPtr((Ptr)huffman_dictionary); | |
| entryptr = huffman_dictionary = (void *)NewPtr(sizeof(short) * (maxentry+1)); | |
| while (maxentry-- >= 0) { | |
| *entryptr++ = (signed char)read_byte(picfile); | |
| } | |
| } | |
| get_num_pictures(void) | |
| { | |
| return max_pic_index; | |
| } /* get_num_pictures */ | |
| int get_picture_size(zword_t picture_number, zword_t *w, zword_t *h) | |
| { | |
| int picture_sequence; | |
| if (picture_directory == NULL) | |
| read_picture_data(); | |
| if ((picture_number <= max_pic_index) && | |
| ((picture_sequence = pic_index[picture_number]) != -1)) { | |
| if (picture_directory[picture_sequence].image_number != picture_number) | |
| DebugStr("\pMisindexed pictures"); | |
| *w = picture_directory[picture_sequence].image_width; | |
| *h = picture_directory[picture_sequence].image_height; | |
| if (!(picture_directory[picture_sequence].image_flags&NOT_COLOR_DOUBLE)) { | |
| *w <<= 1; | |
| *h <<= 1; | |
| } | |
| } | |
| else { | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } /* get_picture_size */ | |
| RgnHandle pixmaptorgn(unsigned char *pixmap, int width, int height) | |
| /* constructs a region containing the non-zero areas in the pixmap */ | |
| /* The region originates at 0,0 */ | |
| { | |
| unsigned char *row; | |
| unsigned char *rowflags; | |
| unsigned char current = 0; | |
| unsigned char row_num_flag; | |
| unsigned char emptyflag = 1; | |
| RgnHandle outputrgn; | |
| RgnPtr rgnptr; | |
| unsigned short *curptr; | |
| int i,j; | |
| int rgnleft, rgnright, rgntop, rgnbottom; | |
| row = pixmap; | |
| rowflags = (unsigned char *)NewPtrClear((size_t)width + 1); | |
| outputrgn = (RgnHandle)NewHandle(sizeof(Region)); | |
| HLock((Handle)outputrgn); | |
| rgnptr = *outputrgn; | |
| rgnptr->rgnBBox.top = 0; | |
| rgnptr->rgnBBox.left = 0; | |
| rgnptr->rgnBBox.bottom = height; | |
| rgnptr->rgnBBox.right = width; | |
| rgnleft = width; | |
| rgnright = 0; | |
| rgntop = height; | |
| rgnbottom = 0; | |
| rgnptr->rgnSize = sizeof(Region); | |
| curptr = (unsigned short *)(rgnptr+1); | |
| for (j = 0; j <= height; j++) { | |
| row_num_flag = 0; | |
| for (i = 0; i <= width; i++) { | |
| if (rowflags[i]) | |
| current = !current; | |
| if ((((j == height) || (i == width))?0:(row[i]!=0)) != (current != 0)) { | |
| if (!row_num_flag) { | |
| OUTPUT(j); | |
| row_num_flag = 1; | |
| emptyflag = 0; | |
| } | |
| OUTPUT(i); | |
| if (i > rgnright) rgnright = i; | |
| if (i < rgnleft) rgnleft = i; | |
| if (j < rgntop) rgntop = j; | |
| if (j > rgnbottom) rgnbottom = j; | |
| current = !current; | |
| rowflags[i] = !rowflags[i]; | |
| } | |
| } | |
| if (row_num_flag) | |
| OUTPUT(0x7FFF); | |
| row += width; | |
| } | |
| if (!emptyflag) { | |
| OUTPUT(0x7FFF); | |
| rgnptr->rgnBBox.top = rgntop; | |
| rgnptr->rgnBBox.left = rgnleft; | |
| rgnptr->rgnBBox.bottom = rgnbottom; | |
| rgnptr->rgnBBox.right = rgnright; | |
| } | |
| DisposPtr((Ptr)rowflags); | |
| rgnptr->rgnSize = ((unsigned long)curptr - (unsigned long)rgnptr); | |
| SetHandleSize((Handle)outputrgn, (size_t)rgnptr->rgnSize); | |
| HUnlock((Handle)outputrgn); | |
| return outputrgn; | |
| } | |
| void os_draw_picture(x, y, n, reverse) | |
| int x,y,n; | |
| { | |
| zword_t w,h; | |
| int i,j,err; | |
| Rect r; | |
| BitMap bm; | |
| GrafPtr saveport; | |
| PenState p; | |
| RgnHandle rgn; | |
| RGBColor saved_fg, saved_bg; | |
| PixMapHandle mypmh; | |
| unsigned char *mypixels, *ipixels, *image; | |
| unsigned long rowbytes; | |
| GWorldPtr mygworld; | |
| CTabHandle myctab; | |
| colormap_t *colormap; | |
| RgnHandle maskrgn; | |
| w = picture_directory[pic_index[n]].image_width; | |
| h = picture_directory[pic_index[n]].image_height; | |
| r.left = x - 1 ; | |
| r.right = x - 1 + w; | |
| r.top = y - 1; | |
| r.bottom = y - 1 + h; | |
| GetPort(&saveport); | |
| SetPort(FrontWindow()); | |
| bm.bounds = r; | |
| ipixels = image = get_image(picfile, &picture_directory[pic_index[n]]); | |
| bm.rowBytes = ((w+15)>>3)&~1; | |
| maskrgn = pixmaptorgn(ipixels, w, h); | |
| maskrgn = NewRgn(); | |
| SetRectRgn(maskrgn, 0, 0, w, h); | |
| OffsetRgn(maskrgn, r.left, r.top); | |
| if (picfile_header.flags&NOT_COLOR_DOUBLE){ | |
| bm.baseAddr = (void *)NewPtrClear(bm.rowBytes * (long)h); | |
| for (i = 0, mypixels = (unsigned char *)bm.baseAddr; i < h; i++, ipixels+=w, mypixels+=bm.rowBytes) { | |
| for (j = 0; j < w; j++) | |
| mypixels[j/8] |= (ipixels[j]&1) << (7-(j&7)); | |
| } | |
| } | |
| else { | |
| colormap = get_color_table(picfile, &picture_directory[pic_index[n]]); | |
| if (colormap != NULL) { | |
| myctab = (CTabHandle)NewHandleClear(sizeof(ColorTable) + sizeof(CSpecArray)*(colormap->num_colors+1)); | |
| (**myctab).ctSeed = GetCTSeed(); | |
| (**myctab).ctSize = colormap->num_colors + 1; | |
| (**myctab).ctFlags |= 0x8000; | |
| (**myctab).ctTable[0].rgb.red = 0xFFFF; | |
| (**myctab).ctTable[0].rgb.green = 0xFFFF; | |
| (**myctab).ctTable[0].rgb.blue = 0xFFFF; | |
| (**myctab).ctTable[1].rgb.red = 0; | |
| (**myctab).ctTable[1].rgb.green = 0; | |
| (**myctab).ctTable[1].rgb.blue = 0; | |
| for (i = 2; i < (colormap->num_colors + 2); i++) { | |
| (**myctab).ctTable[i].rgb.red = colormap->table[i-2][RED]<<8; | |
| (**myctab).ctTable[i].rgb.green = colormap->table[i-2][GREEN]<<8; | |
| (**myctab).ctTable[i].rgb.blue = colormap->table[i-2][BLUE]<<8; | |
| } | |
| DisposPtr((Ptr)colormap); | |
| } | |
| else { | |
| myctab = NULL; | |
| } | |
| err = NewGWorld(&mygworld, 8, &r, myctab /*CTable*/, | |
| /*GDevice*/NULL, keepLocal|useTempMem); | |
| DisposHandle((Handle)myctab); | |
| mypmh = GetGWorldPixMap(mygworld); | |
| LockPixels(mypmh); | |
| rowbytes = (**mypmh).rowBytes&0x3FFF; | |
| mypixels = (unsigned char *)GetPixBaseAddr(mypmh); | |
| for (i = 0; i < h; i++, ipixels+=w, mypixels+=rowbytes) { | |
| memcpy(mypixels, ipixels, w); | |
| } | |
| } | |
| DisposPtr((Ptr)image); | |
| get_picture_size(n, &w, &h); /* this takes any doubling into account. Who made up this stuff? */ | |
| r.left = x - 1 ; | |
| r.right = x - 1 + w; | |
| r.top = y - 1; | |
| r.bottom = y - 1 + h; | |
| GetForeColor(&saved_fg); | |
| GetBackColor(&saved_bg); | |
| ForeColor(blackColor); | |
| BackColor(whiteColor); | |
| OffsetRect(&r, BORDER, BORDER); | |
| MapRgn(maskrgn, &bm.bounds, &r); | |
| if (picfile_header.flags&NOT_COLOR_DOUBLE){ | |
| CopyBits(&bm, &qd.thePort->portBits, &bm.bounds, &r, srcCopy, maskrgn); | |
| } | |
| else { | |
| CopyBits((BitMap *)*mypmh, &qd.thePort->portBits, &bm.bounds, &r, srcCopy, maskrgn); | |
| } | |
| ValidRect(&r); | |
| GetPenState(&p); | |
| PenMode(patCopy); | |
| rgn = NewRgn(); | |
| RectRgn(rgn, &r); | |
| FillRgn(rgn, qd.gray); | |
| FrameRgn(rgn); | |
| DisposeRgn(rgn); | |
| SetPenState(&p); | |
| RGBForeColor(&saved_fg); | |
| RGBBackColor(&saved_bg); | |
| DisposeHandle((Handle)maskrgn); | |
| if (picfile_header.flags&NOT_COLOR_DOUBLE) { | |
| DisposPtr(bm.baseAddr); | |
| } | |
| else { | |
| UnlockPixels(mypmh); | |
| DisposeGWorld(mygworld); | |
| } | |
| SetPort(saveport); | |
| } | |
| void os_erase_picture(x, y, n) | |
| int x,y,n; | |
| { | |
| zword_t w,h; | |
| Rect r; | |
| GrafPtr saveport; | |
| PenState p; | |
| get_picture_size(n, &w, &h); | |
| r.left = x - 1 ; | |
| r.right = x - 1 + w; | |
| r.top = y - 1; | |
| r.bottom = y - 1 + h; | |
| GetPort(&saveport); | |
| SetPort(FrontWindow()); | |
| GetPenState(&p); | |
| PenMode(patCopy); | |
| OffsetRect(&r, BORDER, BORDER); | |
| EraseRect(&r); | |
| SetPenState(&p); | |
| SetPort(saveport); | |
| } | |
| static colormap_t *get_color_table(FILE *fp, pdirectory_t *directory) | |
| static colormap_t *get_color_table (fp, directory) | |
| FILE *fp; | |
| pdirectory_t *directory; | |
| { | |
| colormap_t *result = NULL; | |
| unsigned char num_colors; | |
| int i; | |
| static unsigned char last_colourmap[16][3] = { | |
| 0, 0, 0, | |
| 0, 0,170, | |
| 0,170, 0, | |
| 0,170,170, | |
| 170, 0, 0, | |
| 170, 0,170, | |
| 170,170, 0, | |
| 170,170,170, | |
| 85, 85, 85, | |
| 85, 85,255, | |
| 85,255, 85, | |
| 85,255,255, | |
| 255, 85, 85, | |
| 255, 85,255, | |
| 255,255, 85, | |
| 255,255,255 | |
| }; | |
| num_colors=0; | |
| if (directory->image_cm_addr) { | |
| if (fseek (fp, directory->image_cm_addr, SEEK_SET) != 0) { | |
| perror ("fseek"); | |
| exit (EXIT_FAILURE); | |
| } | |
| num_colors = read_byte (fp); | |
| } | |
| result = (void *)NewPtr(sizeof(colormap_t) + (sizeof(color_t) * ((short)MAX(num_colors,16) - 1))); | |
| for (i = 0; i < num_colors; i++) { | |
| result->table[i][RED] = read_byte (fp); | |
| result->table[i][GREEN] = read_byte (fp); | |
| result->table[i][BLUE] = read_byte (fp); | |
| if (i < 16) { | |
| last_colourmap[i][RED] = result->table[i][RED]; | |
| last_colourmap[i][GREEN] = result->table[i][GREEN]; | |
| last_colourmap[i][BLUE] = result->table[i][BLUE]; | |
| } | |
| } | |
| for (i = num_colors; i < 16; i++) { | |
| result->table[i][RED] = last_colourmap[i][RED]; | |
| result->table[i][GREEN] = last_colourmap[i][GREEN]; | |
| result->table[i][BLUE] = last_colourmap[i][BLUE]; | |
| } | |
| result->num_colors = (num_colors<16)?16:num_colors; | |
| return result; | |
| } | |
| static void *get_image (FILE *fp, pdirectory_t *directory) | |
| static void *get_image (fp, directory) | |
| FILE *fp; | |
| pdirectory_t *directory; | |
| { | |
| int colours = 18, i; | |
| image_t image; | |
| unsigned long image_compsize, image_numcodes; | |
| char *comp_image; | |
| for (i = 0; i < 32; i++) { | |
| colourmap[i][RED] = ega_colourmap[i][RED]; | |
| colourmap[i][GREEN] = ega_colourmap[i][GREEN]; | |
| colourmap[i][BLUE] = ega_colourmap[i][BLUE]; | |
| } | |
| if (directory->image_cm_addr) { | |
| if (fseek (fp, directory->image_cm_addr, SEEK_SET) != 0) { | |
| perror ("fseek"); | |
| exit (EXIT_FAILURE); | |
| } | |
| colours = read_byte (fp); | |
| read_bytes (fp, colours * 3, &colourmap[2][RED]); | |
| colours += 2; | |
| } | |
| /* fprintf (stderr, "Number = %5d, width = %5d, height = %5d, flags = %4x, colourmap = %6ld, data = %6ld, colours = %2d\n", | |
| (int) directory->image_number, (int) directory->image_width, (int) directory->image_height, | |
| (int) directory->image_flags, directory->image_cm_addr, directory->image_data_addr, colours); | |
| */ | |
| if (directory->image_data_addr == 0) | |
| return; | |
| image.width = directory->image_width; | |
| image.height = directory->image_height; | |
| image.colours = colours; | |
| image.pixels = 0; | |
| if ((image.image = (unsigned char *) NewPtr ((size_t)directory->image_width * directory->image_height)) == NULL) { | |
| fprintf (stderr, "Insufficient memory\n"); | |
| exit (EXIT_FAILURE); | |
| } | |
| image.colourmap = colourmap; | |
| if (directory->image_flags & HUFFMAN_FLAG) { | |
| if (!(picfile_header.flags & HUFFMAN_ONEDICT)) { | |
| if (fseek (fp, 2L * directory->huffman_dict_addr, SEEK_SET) != 0) { | |
| perror ("fseek"); | |
| exit (EXIT_FAILURE); | |
| } | |
| get_huffman_dictionary(); | |
| } | |
| if (fseek (fp, directory->image_data_addr, SEEK_SET) != 0) { | |
| perror ("fseek"); | |
| exit (EXIT_FAILURE); | |
| } | |
| if (fseek (fp, directory->image_data_addr, SEEK_SET) != 0) { | |
| perror ("fseek"); | |
| exit (EXIT_FAILURE); | |
| } | |
| image_compsize = 0; | |
| image_numcodes = 0; | |
| fread((char *)&image_compsize + 1, 3, 1, fp); | |
| fread((char *)&image_numcodes + 1, 3, 1, fp); | |
| comp_image = (void *)NewPtr(image_compsize); | |
| fread((char *)comp_image, 1, image_compsize, fp); | |
| unpack_image((unsigned char *)comp_image, (unsigned char *)image.image, | |
| directory->image_width, image_numcodes, (size_t)directory->image_width * directory->image_height); | |
| /* decompress_image (fp, &image);*/ | |
| DisposPtr((Ptr)comp_image); | |
| } | |
| return (image.image); | |
| }/* get image */ | |
| unpack_image(unsigned char *in, unsigned char *out, int width, long numcodes, size_t booga) | |
| { | |
| unsigned long bit=0; | |
| signed char entry, temp; | |
| signed char state = 0; | |
| char *lines, *lastptr, *curptr; | |
| lines = (void *)NewPtrClear(2 * width); | |
| lastptr = lines; | |
| curptr = lines+width; | |
| entry = 0; | |
| do { | |
| if (GETBIT(bit, in)) | |
| entry++; | |
| entry = huffman_dictionary[((unsigned char)entry)]; | |
| if (entry >= 0) { | |
| entry += entry; | |
| } | |
| else { | |
| entry -= 0x90; | |
| if (entry < 0) { | |
| entry += 0x10; | |
| /* here's the wierd XOR with entry */ | |
| temp = entry ^ *lastptr++; | |
| *out++ = temp; | |
| *curptr++ = temp; | |
| if (lastptr == lines+width) { | |
| lastptr = lines; | |
| curptr = lines+width; | |
| memcpy(lastptr, curptr, width); | |
| } | |
| state = entry; | |
| } | |
| else { | |
| do { | |
| /* here's the wierd XOR with state */ | |
| temp = state ^ *lastptr++; | |
| *curptr++ = temp; | |
| *out++ = temp; | |
| if (lastptr == lines+width) { | |
| lastptr = lines; | |
| curptr = lines+width; | |
| memcpy(lastptr, curptr, width); | |
| } | |
| } while (--entry != -1); | |
| } | |
| entry = 0; | |
| numcodes--; | |
| } | |
| bit++; | |
| } | |
| while (numcodes > 0); | |
| DisposPtr((Ptr)lines); | |
| } | |
| static void decompress_image (FILE *fp, image_t *image) | |
| static void decompress_image (fp, image) | |
| FILE *fp; | |
| image_t *image; | |
| { | |
| int i; | |
| short code, old = 0, first, clear_code; | |
| compress_t comp; | |
| clear_code = 1 << CODE_SIZE; | |
| comp.next_code = clear_code + 2; | |
| comp.slen = 0; | |
| comp.sptr = 0; | |
| comp.tlen = CODE_SIZE + 1; | |
| comp.tptr = 0; | |
| for (i = 0; i < CODE_TABLE_SIZE; i++) { | |
| code_table[i][PREFIX] = CODE_TABLE_SIZE; | |
| code_table[i][PIXEL] = i; | |
| } | |
| for (;;) { | |
| if ((code = read_code (fp, &comp)) == (clear_code + 1)) | |
| return; | |
| if (code == clear_code) { | |
| comp.tlen = CODE_SIZE + 1; | |
| comp.next_code = clear_code + 2; | |
| code = read_code (fp, &comp); | |
| } else { | |
| first = (code == comp.next_code) ? old : code; | |
| while (code_table[first][PREFIX] != CODE_TABLE_SIZE) | |
| first = code_table[first][PREFIX]; | |
| code_table[comp.next_code][PREFIX] = old; | |
| code_table[comp.next_code++][PIXEL] = code_table[first][PIXEL]; | |
| } | |
| old = code; | |
| i = 0; | |
| do | |
| buffer[i++] = (unsigned char) code_table[code][PIXEL]; | |
| while ((code = code_table[code][PREFIX]) != CODE_TABLE_SIZE); | |
| do | |
| image->image[image->pixels++] = buffer[--i]; | |
| while (i > 0); | |
| } | |
| }/* decompress_image */ | |
| static short read_code (FILE *fp, compress_t *comp) | |
| static short read_code (fp, comp) | |
| FILE *fp; | |
| compress_t *comp; | |
| { | |
| short code, bsize, tlen, tptr; | |
| int i; | |
| short sw; | |
| code = 0; | |
| tlen = comp->tlen; | |
| tptr = 0; | |
| while (tlen) { | |
| if (comp->slen == 0) { | |
| if ((comp->slen = fread (code_buffer, 1, MAX_BIT, fp)) == 0) { | |
| perror ("fread"); | |
| exit (EXIT_FAILURE); | |
| } | |
| comp->slen *= 8; | |
| comp->sptr = 0; | |
| } | |
| bsize = ((comp->sptr + 8) & ~7) - comp->sptr; | |
| bsize = (tlen > bsize) ? bsize : tlen; | |
| code |= ((code_buffer[comp->sptr >> 3] >> (comp->sptr & 7)) & mask[bsize]) << tptr; | |
| tlen -= bsize; | |
| tptr += bsize; | |
| comp->slen -= bsize; | |
| comp->sptr += bsize; | |
| } | |
| if ((comp->next_code == mask[comp->tlen]) && (comp->tlen < 12)) | |
| comp->tlen++; | |
| return (code); | |
| }/* read_code */ | |
Xet Storage Details
- Size:
- 21.2 kB
- Xet hash:
- 0c1670db2b5c46575a835bed86f53a046ba00b3199e940c7f2ee81420bedaf4b
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.