📄 gvceps.c
字号:
int start = 0; /* start of block to be coded */
BYTE previous = raw[0];
int i, j;
cp = comp;
for (i=0; i<length; i++) {
if (literal == 128) {
/* code now */
*cp++ = (BYTE)(literal-1);
for (j=0; j<literal; j++)
*cp++ = (BYTE)raw[start+j];
prevlit = 0; /* because we can't add to it */
literal = 0;
/* repeat = 0; */ /* implicit */
start = i;
previous = raw[i];
}
if (repeat == 128) {
/* write out repeat block */
*cp++ = (BYTE)-127; /* repeat count 128 */
*cp++ = previous;
repeat = 0;
literal = 0;
start = i;
prevlit = 0;
previous = raw[i];
}
if (raw[i] == previous) {
if (literal == 1) {
/* replace by repeat */
repeat = 1;
literal = 0;
}
else if (literal) {
/* write out existing literal */
literal--; /* remove repeat byte from literal */
*cp++ = (BYTE)(literal-1);
for (j=0; j<literal; j++)
*cp++ = raw[start+j];
if (literal < 126)
prevlit = literal;
else
prevlit = 0; /* we won't be able to add to it */
/* repeat = 0; */ /* implicit */
start = i-1;
repeat = 1;
literal = 0;
}
repeat++;
}
else {
/* doesn't match previous byte */
if (repeat) {
/* write out repeat block, or merge with literal */
if (repeat == 1) {
/* repeats must be 2 bytes or more, so code as literal */
literal = repeat;
repeat = 0;
} else if (repeat == 2) { /* 2 byte repeat */
/* code 2 byte repeat as repeat */
/* except when preceeded by literal */
if ( (prevlit) && (prevlit < 126) ) {
/* previous literal and room to combine */
start -= prevlit; /* continue previous literal */
cp -= prevlit+1;
literal = prevlit + 2;
prevlit = 0;
repeat = 0;
}
else {
/* code as repeat */
*cp++ = (BYTE)(-repeat+1);
*cp++ = previous;
start = i;
prevlit = 0;
/* literal = 0; */ /* implicit */
repeat = 0;
}
/* literals will be coded later */
}
else {
/* repeat of 3 or more bytes */
*cp++ = (BYTE)(-repeat+1);
*cp++ = previous;
start = i;
repeat = 0;
prevlit = 0;
}
}
literal++;
}
previous = raw[i];
}
if (repeat == 1) {
/* can't code repeat 1, use literal instead */
literal = 1;
repeat = 0;
}
if (literal) {
/* code left over literal */
*cp++ = (BYTE)(literal-1);
for (j=0; j<literal; j++)
*cp++ = raw[start+j];
}
if (repeat) {
/* code left over repeat */
*cp++ = (BYTE)(-repeat+1);
*cp++ = previous;
}
return (int)(cp - comp); /* number of code bytes */
}
/* Write tiff file from DIB bitmap */
/* Since this will be used by a DOS EPS file, we write an Intel TIFF file */
int
write_tiff(FILE *f, unsigned char *pbitmap, BOOL tiff4, BOOL use_packbits, BOOL calc_bbox)
{
#define IFD_MAX_ENTRY 12
WORD ifd_length;
DWORD ifd_next;
DWORD tiff_end, end;
int i;
unsigned char *preview;
BYTE *line;
int source_bwidth, bwidth;
BOOL soft_extra = FALSE;
PREBMAP prebmap;
PSBBOX devbbox; /* in pixel units */
int width, height; /* size of preview */
int code;
int bitoffset;
WORD *comp_length=NULL; /* lengths of compressed lines */
BYTE *comp_line=NULL; /* compressed line buffer */
int rowsperstrip;
int stripsperimage;
int strip, is;
int lastrow;
char appname[MAXSTR];
convert_widechar(appname, szAppName, sizeof(appname)-1);
if (*pbitmap == 'P')
code = scan_pbmplus(&prebmap, pbitmap);
else {
code = scan_dib(&prebmap, pbitmap);
}
if (code)
return code;
if (calc_bbox) {
scan_bbox(&prebmap, &devbbox);
if (devbbox.valid) {
/* copy to global bbox as if obtained by PS to EPS */
bbox.llx = (int)(devbbox.llx * 72.0 / option.xdpi - 0.5);
bbox.lly = (int)(devbbox.lly * 72.0 / option.ydpi - 0.5);
bbox.urx = (int)(devbbox.urx * 72.0 / option.xdpi + 1.5);
bbox.ury = (int)(devbbox.ury * 72.0 / option.ydpi + 1.5);
bbox.valid = TRUE;
}
else {
devbbox.urx = prebmap.width;
devbbox.ury = prebmap.height;
devbbox.llx = devbbox.lly = 0;
}
}
else {
#ifdef EPSTOOL
devbbox.urx = prebmap.width;
devbbox.ury = prebmap.height;
devbbox.llx = devbbox.lly = 0;
#else
if (display.epsf_clipped || (psfile.dsc->bbox==(CDSCBBOX *)NULL)) {
/* copy all of display bitmap */
devbbox.urx = prebmap.width;
devbbox.ury = prebmap.height;
devbbox.llx = devbbox.lly = 0;
}
else {
/* copy only part of display bitmap */
devbbox.llx = (int)(psfile.dsc->bbox->llx * option.xdpi / 72.0);
devbbox.lly = (int)(psfile.dsc->bbox->lly * option.ydpi / 72.0);
devbbox.urx = (int)(psfile.dsc->bbox->urx * option.xdpi / 72.0 + 0.5);
devbbox.ury = (int)(psfile.dsc->bbox->ury * option.ydpi / 72.0 + 0.5);
#define LIMIT(z, limit) if (z < 0) z = 0; else if (z > limit) z = limit
LIMIT(devbbox.llx, prebmap.width);
LIMIT(devbbox.lly, prebmap.height);
LIMIT(devbbox.urx, prebmap.width);
LIMIT(devbbox.ury, prebmap.height);
#undef LIMIT
}
#endif
}
width = devbbox.urx - devbbox.llx; /* width of dest bitmap */
height = devbbox.ury - devbbox.lly; /* height of dest bitmap */
/* byte width of preview */
if (tiff4) /* always monochrome */
bwidth = (width + 7) >> 3;
else
bwidth = (width * prebmap.depth + 7) >> 3;
/* byte width of source bitmap */
if (tiff4)
source_bwidth = ((prebmap.width + 7) & ~7) >> 3; /* byte width with 1 bit/pixel */
else
source_bwidth = ((prebmap.width * prebmap.depth + 7) & ~7) >> 3; /* byte width */
if (tiff4)
bitoffset = devbbox.llx;
else
bitoffset = devbbox.llx * prebmap.depth;
if (tiff4)
rowsperstrip = 1; /* make TIFF 4 very simple */
else {
/* work out RowsPerStrip, to give < 8k compressed */
/* or uncompressed data per strip */
rowsperstrip = (8192 - 256) / bwidth;
if (rowsperstrip == 0)
rowsperstrip = 1; /* strips are larger than 8k */
}
stripsperimage = (height + rowsperstrip - 1) / rowsperstrip;
if (stripsperimage == 1)
rowsperstrip = height;
preview = (unsigned char *) malloc(prebmap.bytewidth);
if (preview == NULL)
return 1;
memset(preview,0xff,prebmap.bytewidth);
/* compress bitmap, throwing away result, to find out compressed size */
if (use_packbits) {
comp_length = (WORD *)malloc(stripsperimage * sizeof(WORD));
if (comp_length == NULL) {
free(preview);
return 1;
}
comp_line = (BYTE *)malloc(bwidth + bwidth/64 + 1);
if (comp_line == NULL) {
free(preview);
free(comp_length);
return 1;
}
if (prebmap.bits) {
if (prebmap.topleft)
line = (BYTE *)prebmap.bits + ((long)prebmap.bytewidth * (prebmap.height - devbbox.ury));
else
line = (BYTE *)prebmap.bits + ((long)prebmap.bytewidth * (devbbox.ury-1));
}
else {
return 1;
}
/* process each strip */
for (strip = 0; strip < stripsperimage; strip++) {
is = strip * rowsperstrip;
lastrow = min( rowsperstrip, height - is);
comp_length[strip] = 0;
/* process each line within strip */
for (i = 0; i< lastrow; i++) {
if (tiff4 || prebmap.depth==1)
get_dib_line(line, preview, prebmap.width, prebmap.depth);
else
memmove(preview, line, prebmap.bytewidth);
if (bitoffset)
shift_preview(preview, source_bwidth, bitoffset);
if ( !tiff4 && (*pbitmap != 'P') && (prebmap.depth==24) )
reverse_triples(preview, width);
comp_length[strip] += (WORD)packbits(comp_line, preview, bwidth);
if (prebmap.bits) {
if (prebmap.topleft)
line += prebmap.bytewidth;
else
line -= prebmap.bytewidth;
}
}
}
}
/* write header */
tiff_end = TIFF_HEAD_SIZE;
tiff_word(0x4949, f); /* Intel = little endian */
tiff_word(42, f);
tiff_long(tiff_end, f);
/* write count of ifd entries */
tiff_end += 2 /* sizeof(ifd_length) */;
if (tiff4)
ifd_length = 10;
else {
switch (prebmap.depth) {
case 24:
/* extras are BitsPerPixel, SamplesPerPixel */
ifd_length = 15;
break;
case 8:
case 4:
/* extras are BitsPerPixel, ColorMap */
ifd_length = 15;
break;
default: /* bi-level */
ifd_length = 13;
}
}
tiff_word(ifd_length, f);
tiff_end += ifd_length * TIFF_IFD_SIZE + 4 /* sizeof(ifd_next) */;
ifd_next = 0;
/* write each of the ifd entries */
if (tiff4) {
tiff_word(0xff, f); /* SubfileType */
tiff_word(TIFF_SHORT, f); /* value type */
tiff_long(1, f); /* length */
tiff_short(0, f); /* value */
}
else {
tiff_word(0xfe, f); /* NewSubfileType */
tiff_word(TIFF_LONG, f);
tiff_long(1, f); /* length */
tiff_long(0, f); /* value */
}
tiff_word(0x100, f); /* ImageWidth */
if (tiff4) {
tiff_word(TIFF_SHORT, f);
tiff_long(1, f);
tiff_short((short)width, f);
}
else {
tiff_word(TIFF_LONG, f);
tiff_long(1, f);
tiff_long(width, f);
}
tiff_word(0x101, f); /* ImageHeight */
if (tiff4) {
tiff_word(TIFF_SHORT, f);
tiff_long(1, f);
tiff_short((short)height, f);
}
else {
tiff_word(TIFF_LONG, f);
tiff_long(1, f);
tiff_long(height, f);
}
if (!tiff4 && prebmap.depth>1) {
tiff_word(0x102, f); /* BitsPerSample */
tiff_word(TIFF_SHORT, f);
if (prebmap.depth == 24) {
tiff_long(3, f);
tiff_long(tiff_end, f);
tiff_end += 6;
}
else {
tiff_long(1, f);
tiff_short((WORD)prebmap.depth, f);
}
}
tiff_word(0x103, f); /* Compression */
tiff_word(TIFF_SHORT, f);
tiff_long(1, f);
if (use_packbits)
tiff_short(32773U, f); /* packbits compression */
else
tiff_short(1, f); /* no compression */
tiff_word(0x106, f); /* PhotometricInterpretation */
tiff_word(TIFF_SHORT, f);
tiff_long(1, f);
if (tiff4 || prebmap.depth==1)
tiff_short(1, f); /* black is zero */
else if (prebmap.depth==24)
tiff_short(2, f); /* RGB */
else /* prebmap.depth == 4 or 8 */
tiff_short(3, f); /* Palette Color */
tiff_word(0x111, f); /* StripOffsets */
tiff_word(TIFF_LONG, f);
if (stripsperimage == 1) {
/* This is messy and fragile */
int len = 0;
tiff_long(1, f);
len += TIFF_RATIONAL_SIZE * 2; /* resolutions */
if (!tiff4) {
len += ((strlen(appname)+2)&~1) + 20; /* software and date */
if (prebmap.depth == 4 || prebmap.depth == 8)
len += 2 * 3*(1<<prebmap.depth); /* palette */
}
tiff_long(tiff_end + len, f);
}
else {
tiff_long(stripsperimage, f);
tiff_long(tiff_end, f);
tiff_end += (stripsperimage * 4 /* sizeof(DWORD) */);
}
if (!tiff4 && (prebmap.depth==24)) {
tiff_word(0x115, f); /* SamplesPerPixel */
tiff_word(TIFF_SHORT, f);
tiff_long(1, f);
tiff_short(3, f); /* 3 components */
}
tiff_word(0x116, f); /* RowsPerStrip */
tiff_word(TIFF_LONG, f);
tiff_long(1, f);
tiff_long(rowsperstrip, f);
tiff_word(0x117, f); /* StripByteCounts */
tiff_word(TIFF_LONG, f);
if (stripsperimage == 1) {
tiff_long(1, f);
if (use_packbits)
tiff_long(comp_length[0], f);
else
tiff_long(bwidth * rowsperstrip, f);
}
else {
tiff_long(stripsperimage, f);
tiff_long(tiff_end, f);
tiff_end += (stripsperimage * 4 /* sizeof(DWORD) */);
}
tiff_word(0x11a, f); /* XResolution */
tiff_word(TIFF_RATIONAL, f);
tiff_long(1, f);
tiff_long(tiff_end, f);
tiff_end += TIFF_RATIONAL_SIZE;
tiff_word(0x11b, f); /* YResolution */
tiff_word(TIFF_RATIONAL, f);
tiff_long(1, f);
tiff_long(tiff_end, f);
tiff_end += TIFF_RATIONAL_SIZE;
if (!tiff4) {
tiff_word(0x128, f); /* ResolutionUnit */
tiff_word(TIFF_SHORT, f);
tiff_long(1, f);
tiff_short(2, f); /* inches */
tiff_word(0x131, f); /* Software */
tiff_word(TIFF_ASCII, f);
i = strlen(appname) + 1;
tiff_long(i, f);
tiff_long(tiff_end, f);
tiff_end += i;
if (tiff_end & 1) { /* pad to word boundary */
soft_extra = TRUE;
tiff_end++;
}
tiff_word(0x132, f); /* DateTime */
tiff_word(TIFF_ASCII, f);
tiff_long(20, f);
tiff_long(tiff_end, f);
tiff_end += 20;
if (prebmap.depth==4 || prebmap.depth==8) {
int palcount = 1<<prebmap.depth;
tiff_word(0x140, f); /* ColorMap */
tiff_word(TIFF_SHORT, f);
tiff_long(3*palcount, f); /* size of ColorMap */
tiff_long(tiff_end, f);
tiff_end += 2 * 3*palcount;
}
}
/* write end of ifd tag */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -