stream * s_SHA256E_make_stream(gs_memory_t *mem, byte *digest, int digest_size) { stream *s = s_alloc(mem, "s_SHA256E_make_stream"); stream_state *ss = s_alloc_state(mem, s_SHA256E_template.stype, "s_SHA256E_make_stream"); if (ss == NULL || s == NULL) goto err; ss->templat = &s_SHA256E_template; if (s_init_filter(s, ss, digest, digest_size, NULL) < 0) goto err; s->strm = s; return s; err: gs_free_object(mem, ss, "s_SHA256E_make_stream"); gs_free_object(mem, s, "s_SHA256E_make_stream"); return NULL; }
stream * s_MD5C_make_stream(gs_memory_t *mem, stream *strm) { stream *s = s_alloc(mem, "s_MD5E_make_stream"); stream_state *ss = s_alloc_state(mem, s_MD5E_template.stype, "s_MD5E_make_stream"); int buffer_size = 1024; byte *buffer = gs_alloc_bytes(mem, buffer_size, "s_MD5E_make_stream(buffer)"); if (ss == NULL || s == NULL || buffer == NULL) goto err; ss->templat = &s_MD5C_template; if (s_init_filter(s, ss, buffer, buffer_size, NULL) < 0) goto err; s->strm = strm; s->close_strm = true; return s; err: gs_free_object(mem, ss, "s_MD5E_make_stream"); gs_free_object(mem, s, "s_MD5E_make_stream"); gs_free_object(mem, buffer, "s_MD5E_make_stream"); return NULL; }
/* Write the definition of a Type 1 font. */ int psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options, gs_glyph *orig_subset_glyphs, uint orig_subset_size, const gs_const_string *alt_font_name, int lengths[3]) { stream *es = s; long start = stell(s); param_printer_params_t ppp; printer_param_list_t rlist; gs_param_list *const plist = (gs_param_list *)&rlist; stream AXE_stream; stream_AXE_state AXE_state; byte AXE_buf[200]; /* arbitrary */ stream exE_stream; stream_exE_state exE_state; byte exE_buf[200]; /* arbitrary */ psf_outline_glyphs_t glyphs; int lenIV = pfont->data.lenIV; int (*write_CharString)(stream *, const void *, uint) = stream_write; int code = psf_get_type1_glyphs(&glyphs, pfont, orig_subset_glyphs, orig_subset_size); if (code < 0) return code; /* Initialize the parameter printer. */ ppp = param_printer_params_default; ppp.item_suffix = " def\n"; ppp.print_ok = (options & WRITE_TYPE1_ASCIIHEX ? 0 : PRINT_BINARY_OK) | PRINT_HEX_NOT_OK; code = s_init_param_printer(&rlist, &ppp, s); if (code < 0) return code; /* Write the font header. */ stream_puts(s, "%!FontType1-1.0: "); write_font_name(s, pfont, alt_font_name, false); stream_puts(s, "\n11 dict begin\n"); /* Write FontInfo. */ stream_puts(s, "/FontInfo 5 dict dup begin"); { gs_font_info_t info; int code = pfont->procs.font_info((gs_font *)pfont, NULL, (FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE | FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME), &info); if (code >= 0) { write_font_info(s, "Copyright", &info.Copyright, info.members & FONT_INFO_COPYRIGHT); write_font_info(s, "Notice", &info.Notice, info.members & FONT_INFO_NOTICE); write_font_info(s, "FamilyName", &info.FamilyName, info.members & FONT_INFO_FAMILY_NAME); write_font_info(s, "FullName", &info.FullName, info.members & FONT_INFO_FULL_NAME); } } stream_puts(s, "\nend readonly def\n"); /* Write the main font dictionary. */ stream_puts(s, "/FontName "); write_font_name(s, pfont, alt_font_name, true); stream_puts(s, " def\n"); code = write_Encoding(s, pfont, options, glyphs.subset_glyphs, glyphs.subset_size, glyphs.notdef); if (code < 0) return code; pprintg6(s, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", pfont->FontMatrix.xx, pfont->FontMatrix.xy, pfont->FontMatrix.yx, pfont->FontMatrix.yy, pfont->FontMatrix.tx, pfont->FontMatrix.ty); write_uid(s, &pfont->UID); pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n", pfont->FontBBox.p.x, pfont->FontBBox.p.y, pfont->FontBBox.q.x, pfont->FontBBox.q.y); { static const gs_param_item_t font_items[] = { {"FontType", gs_param_type_int, offset_of(gs_font_type1, FontType)}, {"PaintType", gs_param_type_int, offset_of(gs_font_type1, PaintType)}, {"StrokeWidth", gs_param_type_float, offset_of(gs_font_type1, StrokeWidth)}, gs_param_item_end }; code = gs_param_write_items(plist, pfont, NULL, font_items); if (code < 0) return code; } { const gs_type1_data *const pdata = &pfont->data; write_float_array(plist, "WeightVector", pdata->WeightVector.values, pdata->WeightVector.count); } stream_puts(s, "currentdict end\n"); /* Write the Private dictionary. */ if (lenIV < 0 && (options & WRITE_TYPE1_WITH_LENIV)) { /* We'll have to encrypt the CharStrings. */ lenIV = 0; write_CharString = stream_write_encrypted; } if (options & WRITE_TYPE1_EEXEC) { stream_puts(s, "currentfile eexec\n"); lengths[0] = stell(s) - start; start = stell(s); if (options & WRITE_TYPE1_ASCIIHEX) { s_init(&AXE_stream, s->memory); s_init_state((stream_state *)&AXE_state, &s_AXE_template, NULL); AXE_state.EndOfData = false; s_init_filter(&AXE_stream, (stream_state *)&AXE_state, AXE_buf, sizeof(AXE_buf), es); es = &AXE_stream; } s_init(&exE_stream, s->memory); s_init_state((stream_state *)&exE_state, &s_exE_template, NULL); exE_state.cstate = 55665; s_init_filter(&exE_stream, (stream_state *)&exE_state, exE_buf, sizeof(exE_buf), es); es = &exE_stream; /* * Note: eexec encryption always writes/skips 4 initial bytes, not * the number of initial bytes given by pdata->lenIV. */ stream_puts(es, "****"); } code = write_Private(es, pfont, glyphs.subset_glyphs, glyphs.subset_size, glyphs.notdef, lenIV, write_CharString, &ppp); if (code < 0) return code; stream_puts(es, "dup/FontName get exch definefont pop\n"); if (options & WRITE_TYPE1_EEXEC) { if (options & (WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_EEXEC_MARK)) stream_puts(es, "mark "); stream_puts(es, "currentfile closefile\n"); s_close_filters(&es, s); lengths[1] = stell(s) - start; start = stell(s); if (options & WRITE_TYPE1_EEXEC_PAD) { int i; for (i = 0; i < 8; ++i) stream_puts(s, "\n0000000000000000000000000000000000000000000000000000000000000000"); stream_puts(s, "\ncleartomark\n"); } lengths[2] = stell(s) - start; } else { lengths[0] = stell(s) - start; lengths[1] = lengths[2] = 0; } /* Wrap up. */ s_release_param_printer(&rlist); return 0; }
/* * Create an Indexed color space. This is a single-use procedure, * broken out only for readability. */ static int pdf_indexed_color_space(gx_device_pdf *pdev, cos_value_t *pvalue, const gs_color_space *pcs, cos_array_t *pca) { const gs_indexed_params *pip = &pcs->params.indexed; const gs_color_space *base_space = pcs->base_space; int num_entries = pip->hival + 1; int num_components = gs_color_space_num_components(base_space); uint table_size = num_entries * num_components; /* Guess at the extra space needed for PS string encoding. */ uint string_size = 2 + table_size * 4; uint string_used; byte buf[100]; /* arbitrary */ stream_AXE_state st; stream s, es; gs_memory_t *mem = pdev->pdf_memory; byte *table; byte *palette; cos_value_t v; int code; /* PDF doesn't support Indexed color spaces with more than 256 entries. */ if (num_entries > 256) return_error(gs_error_rangecheck); if (pdev->CompatibilityLevel < 1.3) { switch (gs_color_space_get_index(pcs)) { case gs_color_space_index_Pattern: case gs_color_space_index_Separation: case gs_color_space_index_Indexed: case gs_color_space_index_DeviceN: return_error(gs_error_rangecheck); default: DO_NOTHING; } } table = gs_alloc_string(mem, string_size, "pdf_color_space(table)"); palette = gs_alloc_string(mem, table_size, "pdf_color_space(palette)"); if (table == 0 || palette == 0) { gs_free_string(mem, palette, table_size, "pdf_color_space(palette)"); gs_free_string(mem, table, string_size, "pdf_color_space(table)"); return_error(gs_error_VMerror); } s_init(&s, mem); swrite_string(&s, table, string_size); s_init(&es, mem); s_init_state((stream_state *)&st, &s_PSSE_template, NULL); s_init_filter(&es, (stream_state *)&st, buf, sizeof(buf), &s); sputc(&s, '('); if (pcs->params.indexed.use_proc) { gs_client_color cmin, cmax; byte *pnext = palette; int i, j; /* Find the legal range for the color components. */ for (j = 0; j < num_components; ++j) cmin.paint.values[j] = (float)min_long, cmax.paint.values[j] = (float)max_long; gs_color_space_restrict_color(&cmin, base_space); gs_color_space_restrict_color(&cmax, base_space); /* * Compute the palette values, with the legal range for each * one mapped to [0 .. 255]. */ for (i = 0; i < num_entries; ++i) { gs_client_color cc; gs_cspace_indexed_lookup(pcs, i, &cc); for (j = 0; j < num_components; ++j) { float v = (cc.paint.values[j] - cmin.paint.values[j]) * 255 / (cmax.paint.values[j] - cmin.paint.values[j]); *pnext++ = (v <= 0 ? 0 : v >= 255 ? 255 : (byte)v); } } } else memcpy(palette, pip->lookup.table.data, table_size); if (gs_color_space_get_index(base_space) == gs_color_space_index_DeviceRGB ) { /* Check for an all-gray palette3. */ int i; for (i = table_size; (i -= 3) >= 0; ) if (palette[i] != palette[i + 1] || palette[i] != palette[i + 2] ) break; if (i < 0) { /* Change the color space to DeviceGray. */ for (i = 0; i < num_entries; ++i) palette[i] = palette[i * 3]; table_size = num_entries; base_space = gs_cspace_new_DeviceGray(mem); } } stream_write(&es, palette, table_size); gs_free_string(mem, palette, table_size, "pdf_color_space(palette)"); sclose(&es); sflush(&s); string_used = (uint)stell(&s); table = gs_resize_string(mem, table, string_size, string_used, "pdf_color_space(table)"); /* * Since the array is always referenced by name as a resource * rather than being written as a value, even for in-line images, * always use the full name for the color space. * * We don't have to worry about the range of the base space: * in PDF, unlike PostScript, the values from the lookup table are * scaled automatically. */ if ((code = pdf_color_space(pdev, pvalue, NULL, base_space, &pdf_color_space_names, false)) < 0 || (code = cos_array_add(pca, cos_c_string_value(&v, pdf_color_space_names.Indexed /*pcsn->Indexed*/))) < 0 || (code = cos_array_add(pca, pvalue)) < 0 || (code = cos_array_add_int(pca, pip->hival)) < 0 || (code = cos_array_add_no_copy(pca, cos_string_value(&v, table, string_used))) < 0 ) return code; return 0; }