📄 dscparse.c
字号:
dsc->begin_procset_count = 0;
dsc->data_length = 0;
dsc->data_index = 0;
dsc->data_offset = 0;
dsc->eof = 0;
dsc->line = 0;
dsc->line_length = 0;
dsc->eol = 0;
dsc->last_cr = FALSE;
dsc->line_count = 1;
dsc->long_line = FALSE;
memset(dsc->last_line, 0, sizeof(dsc->last_line));
dsc->string = dsc->string_head;
while (dsc->string != (CDSCSTRING *)NULL) {
if (dsc->string->data)
dsc_memfree(dsc, dsc->string->data);
dsc->string_head = dsc->string;
dsc->string = dsc->string->next;
dsc_memfree(dsc, dsc->string_head);
}
dsc->string_head = NULL;
dsc->string = NULL;
/* don't touch caller functions */
/* public data */
if (dsc->hires_bbox)
dsc_memfree(dsc, dsc->hires_bbox);
dsc->hires_bbox = NULL;
if (dsc->crop_box)
dsc_memfree(dsc, dsc->crop_box);
dsc->crop_box = NULL;
if (dsc->dcs2) {
CDCS2 *this_dcs, *next_dcs;
this_dcs = dsc->dcs2;
while (this_dcs) {
next_dcs = this_dcs->next;
/* strings have already been freed */
dsc_memfree(dsc, this_dcs);
this_dcs = next_dcs;
}
dsc->dcs2 = NULL;
}
if (dsc->colours) {
CDSCCOLOUR *this_colour, *next_colour;
this_colour = dsc->colours;
while (this_colour) {
next_colour = this_colour->next;
/* strings have already been freed */
dsc_memfree(dsc, this_colour);
this_colour = next_colour;
}
dsc->colours = NULL;
}
if (dsc->macbin)
dsc_memfree(dsc, dsc->macbin);
dsc->macbin = NULL;
}
/*
* Join up all sections.
* There might be extra code between them, or we might have
* missed including the \n which followed \r.
* begin is the start of this section
* pend is a pointer to the end of this section
* pplast is a pointer to a pointer of the end of the previous section
*/
dsc_private void
dsc_section_join(DSC_OFFSET begin, DSC_OFFSET *pend, DSC_OFFSET **pplast)
{
if (begin)
**pplast = begin;
if (*pend > begin)
*pplast = pend;
}
/* return value is 0 if no line available, or length of line */
dsc_private int
dsc_read_line(CDSC *dsc)
{
char *p, *last;
dsc->line = NULL;
if (dsc->eof) {
/* return all that remains, even if line incomplete */
dsc->line = dsc->data + dsc->data_index;
dsc->line_length = dsc->data_length - dsc->data_index;
dsc->data_index = dsc->data_length;
return dsc->line_length;
}
if (dsc->file_length &&
(dsc->data_offset + dsc->data_index >= dsc->file_length)) {
/* Have read past where we need to parse. */
/* Ignore all that remains. */
dsc->line = dsc->data + dsc->data_index;
dsc->line_length = dsc->data_length - dsc->data_index;
dsc->data_index = dsc->data_length;
return dsc->line_length;
}
if (dsc->doseps_end &&
(dsc->data_offset + dsc->data_index >= dsc->doseps_end)) {
/* Have read past end of DOS EPS PostScript section. */
/* Ignore all that remains. */
dsc->line = dsc->data + dsc->data_index;
dsc->line_length = dsc->data_length - dsc->data_index;
dsc->data_index = dsc->data_length;
return dsc->line_length;
}
/* ignore embedded bytes */
if (dsc->skip_bytes) {
int cnt = min(dsc->skip_bytes,
(int)(dsc->data_length - dsc->data_index));
dsc->skip_bytes -= cnt;
dsc->data_index += cnt;
if (dsc->skip_bytes != 0)
return 0;
}
do {
dsc->line = dsc->data + dsc->data_index;
last = dsc->data + dsc->data_length;
if (dsc->data_index == dsc->data_length) {
dsc->line_length = 0;
return 0;
}
if (dsc->eol) {
/* if previous line was complete, increment line count */
dsc->line_count++;
if (dsc->skip_lines)
dsc->skip_lines--;
}
/* skip over \n which followed \r */
if (dsc->last_cr && dsc->line[0] == '\n') {
dsc->data_index++;
dsc->line++;
}
dsc->last_cr = FALSE;
/* look for EOL */
dsc->eol = FALSE;
for (p = dsc->line; p < last; p++) {
if (*p == '\r') {
p++;
if ((p<last) && (*p == '\n'))
p++; /* include line feed also */
else
dsc->last_cr = TRUE; /* we might need to skip \n */
dsc->eol = TRUE; /* dsc->line is a complete line */
break;
}
if (*p == '\n') {
p++;
dsc->eol = TRUE; /* dsc->line is a complete line */
break;
}
if (*p == '\032') { /* MS-DOS Ctrl+Z */
dsc->eol = TRUE;
}
}
if (dsc->eol == FALSE) {
/* we haven't got a complete line yet */
if (dsc->data_length - dsc->data_index < sizeof(dsc->data)/2) {
/* buffer is less than half full, ask for some more */
dsc->line_length = 0;
return 0;
}
}
dsc->data_index += dsc->line_length = (int)(p - dsc->line);
} while (dsc->skip_lines && dsc->line_length);
if (dsc->line_length == 0)
return 0;
if ((dsc->line[0]=='%') && (dsc->line[1]=='%')) {
/* handle recursive %%BeginDocument */
if ((dsc->skip_document) && dsc->line_length &&
COMPARE(dsc->line, "%%EndDocument")) {
dsc->skip_document--;
}
/* handle embedded lines or binary data */
if (COMPARE(dsc->line, "%%BeginData:")) {
/* %%BeginData: <numberof>[ <type> [ <bytesorlines> ] ]
* <numberof> ::= <uint> (Lines or physical bytes)
* <type> ::= Hex | Binary | ASCII (Type of data)
* <bytesorlines> ::= Bytes | Lines (Read in bytes or lines)
*/
char begindata[MAXSTR+1];
int cnt;
const char *numberof, *bytesorlines;
cnt = dsc->line_length;
if (dsc->line_length > sizeof(begindata)-1)
cnt = sizeof(begindata)-1;
memcpy(begindata, dsc->line, cnt);
begindata[cnt] = '\0';
numberof = strtok(begindata+12, " \r\n");
strtok(NULL, " \r\n"); /* dump type */
bytesorlines = strtok(NULL, " \r\n");
if (bytesorlines == NULL)
bytesorlines = "Bytes";
if ( (numberof == NULL) || (bytesorlines == NULL) ) {
/* invalid usage of %%BeginData */
/* ignore that we ever saw it */
int rc = dsc_error(dsc, CDSC_MESSAGE_INCORRECT_USAGE,
dsc->line, dsc->line_length);
switch (rc) {
case CDSC_RESPONSE_OK:
case CDSC_RESPONSE_CANCEL:
break;
case CDSC_RESPONSE_IGNORE_ALL:
return 0;
}
}
else {
cnt = atoi(numberof);
if (cnt) {
if (bytesorlines && (dsc_stricmp(bytesorlines, "Lines")==0)) {
/* skip cnt lines */
if (dsc->skip_lines == 0) {
/* we are not already skipping lines */
dsc->skip_lines = cnt+1;
}
}
else {
/* byte count doesn't includes \n or \r\n */
/* or \r of %%BeginData: */
/* skip cnt bytes */
if (dsc->skip_bytes == 0) {
/* we are not already skipping lines */
dsc->skip_bytes = cnt;
}
}
}
}
}
else if (COMPARE(dsc->line, "%%BeginBinary:")) {
/* byte count doesn't includes \n or \r\n or \r of %%BeginBinary:*/
int cnt = dsc_get_int(dsc->line + 14,
dsc->line_length - 14, NULL);
if (dsc->skip_bytes == 0) {
/* we are not already skipping lines */
dsc->skip_bytes = cnt;
}
}
}
if ((dsc->line[0]=='%') && (dsc->line[1]=='%') &&
COMPARE(dsc->line, "%%BeginDocument:") ) {
/* Skip over embedded document, recursively */
dsc->skip_document++;
}
if (!dsc->long_line && (dsc->line_length > DSC_LINE_LENGTH)) {
dsc_error(dsc, CDSC_MESSAGE_LONG_LINE, dsc->line, dsc->line_length);
dsc->long_line = TRUE;
}
return dsc->line_length;
}
/* Save last DSC line, for use with %%+ */
dsc_private void
dsc_save_line(CDSC *dsc)
{
int len = min(sizeof(dsc->last_line), dsc->line_length);
memcpy(dsc->last_line, dsc->line, len);
}
/* display unknown DSC line */
dsc_private void
dsc_unknown(CDSC *dsc)
{
if (dsc->debug_print_fn) {
char line[DSC_LINE_LENGTH];
unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length);
sprintf(line, "Unknown in %s section at line %d:\n ",
dsc_scan_section_name[dsc->scan_section], dsc->line_count);
dsc_debug_print(dsc, line);
strncpy(line, dsc->line, length);
line[length] = '\0';
dsc_debug_print(dsc, line);
dsc_debug_print(dsc, "\n");
}
}
dsc_private GSBOOL
dsc_is_section(char *line)
{
if ( !((line[0]=='%') && (line[1]=='%')) )
return FALSE;
if (IS_DSC(line, "%%BeginPreview"))
return TRUE;
if (IS_DSC(line, "%%BeginDefaults"))
return TRUE;
if (IS_DSC(line, "%%BeginProlog"))
return TRUE;
if (IS_DSC(line, "%%BeginSetup"))
return TRUE;
if (IS_DSC(line, "%%Page:"))
return TRUE;
if (IS_DSC(line, "%%Trailer"))
return TRUE;
if (IS_DSC(line, "%%EOF"))
return TRUE;
return FALSE;
}
/* Get little-endian DWORD, used for DOS EPS files */
dsc_private GSDWORD
dsc_get_dword(const unsigned char *buf)
{
GSDWORD dw;
dw = (GSDWORD)buf[0];
dw += ((GSDWORD)buf[1])<<8;
dw += ((GSDWORD)buf[2])<<16;
dw += ((GSDWORD)buf[3])<<24;
return dw;
}
dsc_private GSWORD
dsc_get_word(const unsigned char *buf)
{
GSWORD w;
w = (GSWORD)buf[0];
w |= (GSWORD)(buf[1]<<8);
return w;
}
/* Get big-endian DWORD, used for Mac Binary files */
dsc_private GSDWORD
dsc_get_bigendian_dword(const unsigned char *buf)
{
GSDWORD dw;
dw = (GSDWORD)buf[3];
dw += ((GSDWORD)buf[2])<<8;
dw += ((GSDWORD)buf[1])<<16;
dw += ((GSDWORD)buf[0])<<24;
return dw;
}
dsc_private GSWORD
dsc_get_bigendian_word(const unsigned char *buf)
{
GSWORD w;
w = (GSWORD)buf[1];
w |= (GSWORD)(buf[0]<<8);
return w;
}
dsc_private int
dsc_read_doseps(CDSC *dsc)
{
unsigned char *line = (unsigned char *)dsc->line;
if ((dsc->doseps = (CDSCDOSEPS *)dsc_memalloc(dsc, sizeof(CDSCDOSEPS))) == NULL)
return CDSC_ERROR; /* no memory */
dsc->doseps->ps_begin = dsc_get_dword(line+4);
dsc->doseps->ps_length = dsc_get_dword(line+8);
dsc->doseps->wmf_begin = dsc_get_dword(line+12);
dsc->doseps->wmf_length = dsc_get_dword(line+16);
dsc->doseps->tiff_begin = dsc_get_dword(line+20);
dsc->doseps->tiff_length = dsc_get_dword(line+24);
dsc->doseps->checksum = dsc_get_word(line+28);
if (dsc->file_length &&
(dsc->doseps->ps_begin + dsc->doseps->ps_length > dsc->file_length)) {
/* Error in DOS EPS header.
* Some files have been seen with a fixed large value as
* the length of the PostScript section.
* Correct for these erroneous files.
*/
dsc->doseps->ps_length =
(GSDWORD)(dsc->file_length - dsc->doseps->ps_begin);
}
dsc->doseps_end = dsc->doseps->ps_begin + dsc->doseps->ps_length;
/* move data_index backwards to byte after doseps header */
dsc->data_index -= dsc->line_length - 30;
/* we haven't read a line of PostScript code yet */
dsc->line_count = 0;
/* skip from current position to start of PostScript section */
dsc->skip_bytes = dsc->doseps->ps_begin - 30;
if (dsc->doseps->tiff_begin)
dsc->preview = CDSC_TIFF;
if (dsc->doseps->wmf_begin)
dsc->preview = CDSC_WMF;
return CDSC_OK;
}
dsc_private int
dsc_read_macbin(CDSC *dsc)
{
unsigned char *line = (unsigned char *)dsc->line;
if ((dsc->macbin =
(CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
return CDSC_ERROR; /* no memory */
dsc->macbin->data_begin = 128;
dsc->macbin->data_length = dsc_get_bigendian_dword(line+83);
dsc->macbin->resource_begin =
(dsc->macbin->data_begin + dsc->macbin->data_length + 127 ) & ~127;
dsc->macbin->resource_length = dsc_get_bigendian_dword(line+87);
/* A MacBinary file has been seen that doesn't have the resource
* fork padded out to 128 bytes. Just make sure that the resource
* doesn't extend beyond EOF.
*/
if (dsc->file_length &&
(((dsc->macbin->resource_begin + dsc->macbin->resource_length
/* + 127 */ ) /* & ~127 */ ) > dsc->file_length)) {
return CDSC_ERROR;
}
dsc->doseps_end = dsc->macbin->data_begin + dsc->macbin->data_length;
/* move data_index to byte after Mac Binary header */
dsc->data_index -= dsc->line_length - 128;
/* we haven't read a line of PostScript code yet */
dsc->line_count = 0;
dsc->preview = CDSC_PICT;
return CDSC_OK;
}
dsc_private int
dsc_read_applesingle(CDSC *dsc)
{
GSDWORD EntryID;
GSDWORD Offset;
GSDWORD Length;
GSWORD entries;
int index;
int header;
int i;
unsigned char *line = (unsigned char *)dsc->line;
if ((dsc->macbin =
(CDSCMACBIN *)dsc_memalloc(dsc, sizeof(CDSCMACBIN))) == NULL)
return CDSC_ERROR; /* no memory */
entries = dsc_get_bigendian_word(line+24);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -