⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dscparse.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -