Exemplo n.º 1
0
gslt_font_t *
gslt_new_font(gs_memory_t *mem, gs_font_dir *fontdir, char *buf, int buflen, int subfontid)
{
    gslt_font_t *xf;
    int t;

    xf = (void*) gs_alloc_bytes(mem, sizeof(gslt_font_t), "gslt_font struct");
    if (!xf)
    {
        gs_throw(-1, "out of memory");
        return NULL;
    }

    xf->data = (byte*)buf;
    xf->length = buflen;
    xf->font = NULL;

    xf->subfontid = subfontid;
    xf->cmaptable = 0;
    xf->cmapsubcount = 0;
    xf->cmapsubtable = 0;
    xf->usepua = 0;

    xf->cffdata = 0;
    xf->cffend = 0;
    xf->gsubrs = 0;
    xf->subrs = 0;
    xf->charstrings = 0;

    if (memcmp(xf->data, "OTTO", 4) == 0)
	t = gslt_init_postscript_font(mem, fontdir, xf);
    else if (memcmp(xf->data, "\0\1\0\0", 4) == 0)
	t = gslt_init_truetype_font(mem, fontdir, xf);
    else if (memcmp(xf->data, "true", 4) == 0)
	t = gslt_init_truetype_font(mem, fontdir, xf);
    else if (memcmp(xf->data, "ttcf", 4) == 0)
	t = gslt_init_truetype_font(mem, fontdir, xf);
    else
    {
        gslt_free_font(mem, xf);
	gs_throw(-1, "not an opentype font");
	return NULL;
    }

    if (t < 0)
    {
        gslt_free_font(mem, xf);
        gs_rethrow(-1, "cannot init font");
        return NULL;
    }

    t = gslt_load_sfnt_cmap(xf);
    if (t < 0)
    {
        errprintf("warning: no cmap table found in font\n");
    }

    return xf;
}
Exemplo n.º 2
0
xps_font_t *
xps_new_font(xps_context_t *ctx, byte *buf, int buflen, int index)
{
    xps_font_t *font;
    int code;

    font = xps_alloc(ctx, sizeof(xps_font_t));
    if (!font)
    {
        gs_throw(gs_error_VMerror, "out of memory");
        return NULL;
    }

    font->data = buf;
    font->length = buflen;
    font->font = NULL;

    font->subfontid = index;
    font->cmaptable = 0;
    font->cmapsubcount = 0;
    font->cmapsubtable = 0;
    font->usepua = 0;

    font->cffdata = 0;
    font->cffend = 0;
    font->gsubrs = 0;
    font->subrs = 0;
    font->charstrings = 0;

    if (memcmp(font->data, "OTTO", 4) == 0)
        code = xps_init_postscript_font(ctx, font);
    else if (memcmp(font->data, "\0\1\0\0", 4) == 0)
        code = xps_init_truetype_font(ctx, font);
    else if (memcmp(font->data, "true", 4) == 0)
        code = xps_init_truetype_font(ctx, font);
    else if (memcmp(font->data, "ttcf", 4) == 0)
        code = xps_init_truetype_font(ctx, font);
    else
    {
        xps_free_font(ctx, font);
        gs_throw(-1, "not an opentype font");
        return NULL;
    }

    if (code < 0)
    {
        xps_free_font(ctx, font);
        gs_rethrow(-1, "cannot init font");
        return NULL;
    }

    xps_load_sfnt_cmap(font);

    return font;
}
Exemplo n.º 3
0
/* Store a key in our crypt context */
int
s_aes_set_key(stream_aes_state * state, const unsigned char *key,
                  int keylength)
{
    int code = 0;

    if ( (keylength < 1) || (keylength > SAES_MAX_KEYLENGTH) )
        return_error(gs_error_rangecheck);
    if (key == NULL)
        return_error(gs_error_invalidaccess);

    /* we can't set the key here because the interpreter's
       filter implementation wants to duplicate our state
       after the zfaes.c binding calls us. So stash it now
       and handle it in our process method. */
    memcpy(state->key, key, keylength);
    state->keylength = keylength;

    if (code) {
      return gs_throw(gs_error_rangecheck, "could not set AES key");
    }

    /* return successfully */
    return 0;
}
Exemplo n.º 4
0
static void
xps_add_fixed_document(xps_context_t *ctx, char *name)
{
    xps_document_t *fixdoc;

    /* Check for duplicates first */
    for (fixdoc = ctx->first_fixdoc; fixdoc; fixdoc = fixdoc->next)
        if (!strcmp(fixdoc->name, name))
            return;

    if_debug1m('|', ctx->memory, "doc: adding fixdoc %s\n", name);

    fixdoc = xps_alloc(ctx, sizeof(xps_document_t));
    if (!fixdoc) {
        gs_throw(gs_error_VMerror, "out of memory: xps_add_fixed_document\n");
        return;
    }
    fixdoc->name = xps_strdup(ctx, name);
    fixdoc->next = NULL;

    if (!ctx->first_fixdoc)
    {
        ctx->first_fixdoc = fixdoc;
        ctx->last_fixdoc = fixdoc;
    }
    else
    {
        ctx->last_fixdoc->next = fixdoc;
        ctx->last_fixdoc = fixdoc;
    }
}
Exemplo n.º 5
0
static void
xps_add_fixed_page(xps_context_t *ctx, char *name, int width, int height)
{
    xps_page_t *page;

    /* Check for duplicates first */
    for (page = ctx->first_page; page; page = page->next)
        if (!strcmp(page->name, name))
            return;

    if_debug1m('|', ctx->memory, "doc: adding page %s\n", name);

    page = xps_alloc(ctx, sizeof(xps_page_t));
    if (!page) {
        gs_throw(gs_error_VMerror, "out of memory: xps_add_fixed_page\n");
        return;
    }
    page->name = xps_strdup(ctx, name);
    page->width = width;
    page->height = height;
    page->next = NULL;

    if (!ctx->first_page)
    {
        ctx->first_page = page;
        ctx->last_page = page;
    }
    else
    {
        ctx->last_page->next = page;
        ctx->last_page = page;
    }
}
Exemplo n.º 6
0
/* Common code shared between remap and concretize */
static int
gx_ciea_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, gs_memory_t *memory)
{
    int code;
    gs_color_space *palt_cs = pcs->base_space;
    gx_cie_vector_cache *a_cache = &(pcs->params.a->caches.DecodeA);
    gx_cie_scalar_cache    *lmn_caches = &(pcs->params.a->common.caches.DecodeLMN[0]);

    if_debug0m(gs_debug_flag_icc, memory,
               "[icc] Creating ICC profile from CIEA object");  
    /* build the ICC color space object */
    code = gs_cspace_build_ICC(ppcs_icc, NULL, memory);
    if (code < 0)
        return gs_rethrow(code, "Failed to create ICC profile");
    /* record the cie alt space as the icc alternative color space */
    (*ppcs_icc)->base_space = palt_cs;
    rc_increment_cs(palt_cs);
    (*ppcs_icc)->cmm_icc_profile_data = gsicc_profile_new(NULL, memory, NULL, 0);
    if ((*ppcs_icc)->cmm_icc_profile_data == NULL)
        gs_throw(gs_error_VMerror, "Failed to create ICC profile");
    code = gsicc_create_froma(pcs, &((*ppcs_icc)->cmm_icc_profile_data->buffer),
                    &((*ppcs_icc)->cmm_icc_profile_data->buffer_size), memory,
                    a_cache, lmn_caches);
    if (code < 0)
        return gs_rethrow(code, "Failed to create ICC profile from CIEA");
    code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
    if (code < 0)
        return gs_rethrow(code, "Failed to build ICC profile from CIEDEF");
    (*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_A;
    /* Assign to the icc_equivalent member variable */
    pcs->icc_equivalent = *ppcs_icc;
    pcs->icc_equivalent->cmm_icc_profile_data->data_cs = gsGRAY;
    return 0;
}
Exemplo n.º 7
0
xps_part_t *
xps_new_part(xps_context_t *ctx, char *name, int size)
{
    xps_part_t *part;

    part = xps_alloc(ctx, sizeof(xps_part_t));
    if (!part) {
        gs_throw(gs_error_VMerror, "out of memory: xps_new_part\n");
        return NULL;
    }
    part->name = xps_strdup(ctx, name);
    part->size = size;
    part->data = xps_alloc(ctx, size);
    if (!part->data) {
        xps_free(ctx, part);
        gs_throw(gs_error_VMerror, "out of memory: xps_new_part\n");
        return NULL;
    }

    return part;
}
Exemplo n.º 8
0
static void
xps_decode_jpegxr_block(jxr_image_t image, int mx, int my, int *data)
{
    struct state *state = jxr_get_user_data(image);
    xps_context_t *ctx = state->ctx;
    xps_image_t *output = state->output;
    int depth;
    unsigned char *p;
    int x, y, k;

    if (!output->samples)
    {
        output->width = jxr_get_IMAGE_WIDTH(image);
        output->height = jxr_get_IMAGE_HEIGHT(image);
        output->comps = jxr_get_IMAGE_CHANNELS(image);
        output->hasalpha = jxr_get_ALPHACHANNEL_FLAG(image);
        output->bits = 8;
        output->stride = output->width * output->comps;
        output->samples = xps_alloc(ctx, output->stride * output->height);
        if (!output->samples) {
            gs_throw(gs_error_VMerror, "out of memory: output->samples.\n");
            return;
        }

        switch (output->comps)
        {
        default:
        case 1: output->colorspace = ctx->gray; break;
        case 3: output->colorspace = ctx->srgb; break;
        case 4: output->colorspace = ctx->cmyk; break;
        }
    }

    depth = jxr_get_OUTPUT_BITDEPTH(image);

    my = my * 16;
    mx = mx * 16;

    for (y = 0; y < 16; y++)
    {
        if (my + y >= output->height)
            return;
        p = output->samples + (my + y) * output->stride + mx * output->comps;
        for (x = 0; x < 16; x++)
        {
            if (mx + x >= output->width)
                data += output->comps;
            else
                for (k = 0; k < output->comps; k++)
                    *p++ = scale_bits(depth, *data++);
        }
    }
}
Exemplo n.º 9
0
static char *
svg_make_color(gx_device_svg *svg, const gx_drawing_color *pdc)
{
    char *paint = (char *)gs_alloc_string(svg->memory, 8, "svg_make_color");

    if (!paint) {
        gs_throw(gs_error_VMerror, "string allocation failed");
        return NULL;
    }

    if (gx_dc_is_pure(pdc)) {
        gx_color_index color = gx_dc_pure_color(pdc);
        sprintf(paint, "#%06x", (int)(color & 0xffffffL));
    } else if (gx_dc_is_null(pdc)) {
        sprintf(paint, "None");
    } else {
        gs_free_string(svg->memory, (byte *)paint, 8, "svg_make_color");
        gs_throw(gs_error_rangecheck, "unknown color type");
        return NULL;
    }

    return paint;
}
Exemplo n.º 10
0
int
xps_parse_metadata(xps_context_t *ctx, xps_part_t *part)
{
    XML_Parser xp;
    int code;
    char buf[1024];
    char *s;

    /* Save directory name part */
    xps_strlcpy(buf, part->name, sizeof buf);
    s = strrchr(buf, '/');
    if (s)
        s[0] = 0;

    /* _rels parts are voodoo: their URI references are from
     * the part they are associated with, not the actual _rels
     * part being parsed.
     */
    s = strstr(buf, "/_rels");
    if (s)
        *s = 0;

    ctx->base_uri = buf;
    ctx->part_uri = part->name;

    xp = XML_ParserCreate(NULL);
    if (!xp)
        return gs_throw(-1, "cannot create XML parser");

    XML_SetUserData(xp, ctx);
    XML_SetParamEntityParsing(xp, XML_PARAM_ENTITY_PARSING_NEVER);
    XML_SetStartElementHandler(xp, (XML_StartElementHandler)xps_parse_metadata_imp);

    code = XML_Parse(xp, (char*)part->data, part->size, 1);

    XML_ParserFree(xp);

    ctx->base_uri = NULL;
    ctx->part_uri = NULL;

    if (code == 0)
        return gs_throw1(-1, "cannot parse XML in part: %s", part->name);

    return 0;
}
Exemplo n.º 11
0
xps_item_t *
xps_parse_xml(xps_context_t *ctx, byte *buf, int len)
{
    xps_parser_t parser;
    XML_Parser xp;
    int code;

    parser.ctx = ctx;
    parser.root = NULL;
    parser.head = NULL;
    parser.error = NULL;
    parser.compat = 0;

    xp = XML_ParserCreateNS(NULL, ' ');
    if (!xp)
    {
        gs_throw(-1, "xml error: could not create expat parser");
        return NULL;
    }

    XML_SetUserData(xp, &parser);
    XML_SetParamEntityParsing(xp, XML_PARAM_ENTITY_PARSING_NEVER);
    XML_SetStartElementHandler(xp, (XML_StartElementHandler)on_open_tag);
    XML_SetEndElementHandler(xp, (XML_EndElementHandler)on_close_tag);
    XML_SetCharacterDataHandler(xp, (XML_CharacterDataHandler)on_text);

    code = XML_Parse(xp, (char*)buf, len, 1);
    if (code == 0)
    {
        if (parser.root)
            xps_free_item(ctx, parser.root);
        XML_ParserFree(xp);
        gs_throw1(-1, "xml error: %s", XML_ErrorString(XML_GetErrorCode(xp)));
        return NULL;
    }

    XML_ParserFree(xp);

    if (parser.compat)
        xps_process_compatibility(ctx, parser.root);

    return parser.root;
}
Exemplo n.º 12
0
/*
 * Switch on file magic to decode an image.
 */
gslt_image_t *
gslt_image_decode(gs_memory_t *mem, byte *buf, int len)
{
    gslt_image_t *image = NULL;
    int error = gs_okay;

    if (buf[0] == 0xff && buf[1] == 0xd8)
        image = gslt_image_decode_jpeg(mem, buf, len);
    else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0)
        image = gslt_image_decode_png(mem, buf, len);
    else if (memcmp(buf, "MM", 2) == 0)
        image = gslt_image_decode_tiff(mem, buf, len);
    else if (memcmp(buf, "II", 2) == 0)
        image = gslt_image_decode_tiff(mem, buf, len);
    else
        error = gs_throw(-1, "unknown image file format");

    if (image == NULL)
        error = gs_rethrow(error, "could not decode image");

    return image;
}
Exemplo n.º 13
0
static void
xps_decode_jpegxr_alpha_block(jxr_image_t image, int mx, int my, int *data)
{
    struct state *state = jxr_get_user_data(image);
    xps_context_t *ctx = state->ctx;
    xps_image_t *output = state->output;
    int depth;
    unsigned char *p;
    int x, y, k;

    if (!output->alpha)
    {
        output->alpha = xps_alloc(ctx, output->width * output->height);
        if (!output->alpha) {
            gs_throw(gs_error_VMerror, "out of memory: output->alpha.\n");
            return;
        }
    }

    depth = jxr_get_OUTPUT_BITDEPTH(image);

    my = my * 16;
    mx = mx * 16;

    for (y = 0; y < 16; y++)
    {
        if (my + y >= output->height)
            return;
        p = output->alpha + (my + y) * output->width + mx;
        for (x = 0; x < 16; x++)
        {
            if (mx + x >= output->width)
                data ++;
            else
                *p++ = scale_bits(depth, *data++);
        }
    }
}
Exemplo n.º 14
0
gs_font_dir *
gslt_new_font_cache(gs_memory_t *mem)
{
    gs_font_dir *fontdir;

    int smax = 50;         /* number of scaled fonts */
    int bmax = 500000;     /* space for cached chars */
    int mmax = 200;        /* number of cached font/matrix pairs */
    int cmax = 5000;       /* number of cached chars */
    int upper = 32000;     /* max size of a single cached char */

    fontdir = gs_font_dir_alloc2_limits(mem, mem, smax, bmax, mmax, cmax, upper);
    if (!fontdir)
    {
        gs_throw(-1, "cannot gs_font_dir_alloc2_limits()");
        return NULL;
    }

    gs_setaligntopixels(fontdir, 1); /* no subpixels */
    gs_setgridfittt(fontdir, 3); /* see gx_ttf_outline for values */

    return fontdir;
}
Exemplo n.º 15
0
static void
on_text(void *zp, char *buf, int len)
{
    xps_parser_t *parser = zp;
    xps_context_t *ctx = parser->ctx;
    const char *atts[3];
    int i;

    if (parser->error)
        return;

    for (i = 0; i < len; i++)
    {
        if (!is_xml_space(buf[i]))
        {
            char *tmp = xps_alloc(ctx, len + 1);
            if (!tmp)
            {
                parser->error = "out of memory";
                gs_throw(gs_error_VMerror, "out of memory.\n");
                return;
            }

            atts[0] = "";
            atts[1] = tmp;
            atts[2] = NULL;

            memcpy(tmp, buf, len);
            tmp[len] = 0;
            on_open_tag(zp, "", atts);
            on_close_tag(zp, "");
            xps_free(ctx, tmp);
            return;
        }
    }
}
Exemplo n.º 16
0
int
xps_decode_png(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
{
    png_structp png;
    png_infop info;
    struct xps_png_io_s io;
    int npasses;
    int pass;
    int y;

    /*
     * Set up PNG structs and input source
     */

    io.ptr = rbuf;
    io.lim = rbuf + rlen;

    png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING,
            NULL, NULL, NULL,
            ctx->memory, xps_png_malloc, xps_png_free);
    if (!png)
        return gs_throw(-1, "png_create_read_struct");

    info = png_create_info_struct(png);
    if (!info)
        return gs_throw(-1, "png_create_info_struct");

    png_set_read_fn(png, &io, xps_png_read);
    png_set_crc_action(png, PNG_CRC_WARN_USE, PNG_CRC_WARN_USE);

    /*
     * Jump to here on errors.
     */

    if (setjmp(png_jmpbuf(png)))
    {
        png_destroy_read_struct(&png, &info, NULL);
        return gs_throw(-1, "png reading failed");
    }

    /*
     * Read PNG header
     */

    png_read_info(png, info);

    if (png_get_interlace_type(png, info) == PNG_INTERLACE_ADAM7)
    {
        npasses = png_set_interlace_handling(png);
    }
    else
    {
        npasses = 1;
    }

    if (png_get_color_type(png, info) == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(png);
    }

    if (png_get_valid(png, info, PNG_INFO_tRNS))
    {
        /* this will also expand the depth to 8-bits */
        png_set_tRNS_to_alpha(png);
    }

    png_read_update_info(png, info);

    image->width = png_get_image_width(png, info);
    image->height = png_get_image_height(png, info);
    image->comps = png_get_channels(png, info);
    image->bits = png_get_bit_depth(png, info);

    /* See if we have an icc profile */
    if (info->iccp_profile != NULL)
    {
        image->profilesize = info->iccp_proflen;
        image->profile = xps_alloc(ctx, info->iccp_proflen);
        if (image->profile)
        {
            /* If we can't create it, just ignore */
            memcpy(image->profile, info->iccp_profile, info->iccp_proflen);
        }
    }

    switch (png_get_color_type(png, info))
    {
    case PNG_COLOR_TYPE_GRAY:
        image->colorspace = ctx->gray;
        image->hasalpha = 0;
        break;

    case PNG_COLOR_TYPE_RGB:
        image->colorspace = ctx->srgb;
        image->hasalpha = 0;
        break;

    case PNG_COLOR_TYPE_GRAY_ALPHA:
        image->colorspace = ctx->gray;
        image->hasalpha = 1;
        break;

    case PNG_COLOR_TYPE_RGB_ALPHA:
        image->colorspace = ctx->srgb;
        image->hasalpha = 1;
        break;

    default:
        return gs_throw(-1, "cannot handle this png color type");
    }

    /*
     * Extract DPI, default to 96 dpi
     */

    image->xres = 96;
    image->yres = 96;

    if (info->valid & PNG_INFO_pHYs)
    {
        png_uint_32 xres, yres;
        int unit;
        png_get_pHYs(png, info, &xres, &yres, &unit);
        if (unit == PNG_RESOLUTION_METER)
        {
            image->xres = xres * 0.0254 + 0.5;
            image->yres = yres * 0.0254 + 0.5;
        }
    }

    /*
     * Read rows, filling transformed output into image buffer.
     */

    image->stride = (image->width * image->comps * image->bits + 7) / 8;

    image->samples = xps_alloc(ctx, image->stride * image->height);

    for (pass = 0; pass < npasses; pass++)
    {
        for (y = 0; y < image->height; y++)
        {
            png_read_row(png, image->samples + (y * image->stride), NULL);
        }
    }

    /*
     * Clean up memory.
     */

    png_destroy_read_struct(&png, &info, NULL);

    return gs_okay;
}
Exemplo n.º 17
0
int
xps_init_truetype_font(xps_context_t *ctx, xps_font_t *font)
{
    font->font = (void*) gs_alloc_struct(ctx->memory, gs_font_type42, &st_gs_font_type42, "xps_font type42");
    if (!font->font)
        return gs_throw(gs_error_VMerror, "out of memory");

    /* no shortage of things to initialize */
    {
        gs_font_type42 *p42 = (gs_font_type42*) font->font;

        /* Common to all fonts: */

        p42->next = 0;
        p42->prev = 0;
        p42->memory = ctx->memory;

        p42->dir = ctx->fontdir; /* NB also set by gs_definefont later */
        p42->base = font->font; /* NB also set by gs_definefont later */
        p42->is_resource = false;
        gs_notify_init(&p42->notify_list, gs_memory_stable(ctx->memory));
        p42->id = gs_next_ids(ctx->memory, 1);

        p42->client_data = font; /* that's us */

        /* this is overwritten in grid_fit() */
        gs_make_identity(&p42->FontMatrix);
        gs_make_identity(&p42->orig_FontMatrix); /* NB ... original or zeroes? */

        p42->FontType = ft_TrueType;
        p42->BitmapWidths = false;
        p42->ExactSize = fbit_use_outlines;
        p42->InBetweenSize = fbit_use_outlines;
        p42->TransformedChar = fbit_use_outlines;
        p42->WMode = 0;
        p42->PaintType = 0;
        p42->StrokeWidth = 0;
        p42->is_cached = 0;

        p42->procs.define_font = gs_no_define_font;
        p42->procs.make_font = gs_no_make_font;
        p42->procs.font_info = gs_type42_font_info;
        p42->procs.same_font = gs_default_same_font;
        p42->procs.encode_char = xps_true_callback_encode_char;
        p42->procs.decode_glyph = xps_true_callback_decode_glyph;
        p42->procs.enumerate_glyph = gs_type42_enumerate_glyph;
        p42->procs.glyph_info = gs_type42_glyph_info;
        p42->procs.glyph_outline = gs_type42_glyph_outline;
        p42->procs.glyph_name = xps_true_callback_glyph_name;
        p42->procs.init_fstack = gs_default_init_fstack;
        p42->procs.next_char_glyph = gs_default_next_char_glyph;
        p42->procs.build_char = xps_true_callback_build_char;

        memset(p42->font_name.chars, 0, sizeof(p42->font_name.chars));
        xps_load_sfnt_name(font, (char*)p42->font_name.chars);
        p42->font_name.size = strlen((char*)p42->font_name.chars);

        memset(p42->key_name.chars, 0, sizeof(p42->key_name.chars));
        strcpy((char*)p42->key_name.chars, (char*)p42->font_name.chars);
        p42->key_name.size = strlen((char*)p42->key_name.chars);

        /* Base font specific: */

        p42->FontBBox.p.x = 0;
        p42->FontBBox.p.y = 0;
        p42->FontBBox.q.x = 0;
        p42->FontBBox.q.y = 0;

        uid_set_UniqueID(&p42->UID, p42->id);

        p42->encoding_index = ENCODING_INDEX_UNKNOWN;
        p42->nearest_encoding_index = ENCODING_INDEX_ISOLATIN1;

        p42->FAPI = 0;
        p42->FAPI_font_data = 0;

        /* Type 42 specific: */

        p42->data.string_proc = xps_true_callback_string_proc;
        p42->data.proc_data = font;

        gs_type42_font_init(p42, font->subfontid);
        p42->data.get_glyph_index = xps_true_get_glyph_index;
    }

    gs_definefont(ctx->fontdir, font->font);

    return 0;
}
Exemplo n.º 18
0
static int
xps_true_callback_glyph_name(gs_font *pfont, gs_glyph glyph, gs_const_string *pstr)
{
    /* This function is copied verbatim from plfont.c */

    int table_length;
    int table_offset;

    ulong format;
    uint numGlyphs;
    uint glyph_name_index;
    const byte *postp; /* post table pointer */

    /* guess if the font type is not truetype */
    if ( pfont->FontType != ft_TrueType )
    {
        glyph -= 29;
        if ( glyph >= 0 && glyph < 258 )
        {
            pstr->data = (byte*) pl_mac_names[glyph];
            pstr->size = strlen((char*)pstr->data);
            return 0;
        }
        else
        {
            return gs_throw1(-1, "glyph index %lu out of range", (ulong)glyph);
        }
    }

    table_offset = xps_find_sfnt_table((xps_font_t*)pfont->client_data, "post", &table_length);

    /* no post table */
    if (table_offset < 0)
        return gs_throw(-1, "no post table");

    /* this shoudn't happen but... */
    if ( table_length == 0 )
        return gs_throw(-1, "zero-size post table");

    ((gs_font_type42 *)pfont)->data.string_proc((gs_font_type42 *)pfont,
                                                table_offset, table_length, &postp);
    format = u32(postp);

    /* Format 1.0 (mac encoding) is a simple table see the TT spec.
     * We don't implement this because we don't see it in practice.
     * Format 2.5 is deprecated.
     * Format 3.0 means that there is no post data in the font file.
     * We see this a lot but can't do much about it.
     * The only format we support is 2.0.
     */
    if ( format != 0x20000 )
    {
        /* Invent a name if we don't know the table format. */
        char buf[32];
        sprintf(buf, "glyph%d", (int)glyph);
        pstr->data = (byte*)buf;
        pstr->size = strlen((char*)pstr->data);
        return 0;
    }

    /* skip over the post header */
    numGlyphs = u16(postp + 32);
    if ( glyph < 0 || glyph > numGlyphs - 1)
    {
        return gs_throw1(-1, "glyph index %lu out of range", (ulong)glyph);
    }

    /* glyph name index starts at post + 34 each entry is 2 bytes */
    glyph_name_index = u16(postp + 34 + (glyph * 2));

    /* this shouldn't happen */
    if ( glyph_name_index < 0 && glyph_name_index > 0x7fff )
        return gs_throw(-1, "post table format error");

    /* mac easy */
    if ( glyph_name_index < 258 )
    {
        // dprintf2("glyph name (mac) %d = %s\n", glyph, pl_mac_names[glyph_name_index]);
        pstr->data = (byte*) pl_mac_names[glyph_name_index];
        pstr->size = strlen((char*)pstr->data);
        return 0;
    }

    /* not mac */
    else
    {
        byte *mydata;

        /* and here's the tricky part */
        const byte *pascal_stringp = postp + 34 + (numGlyphs * 2);

        /* 0 - 257 lives in the mac table above */
        glyph_name_index -= 258;

        /* The string we want is the index'th pascal string,
         * so we "hop" to each length byte "index" times. */
        while (glyph_name_index > 0)
        {
            pascal_stringp += ((int)(*pascal_stringp)+1);
            glyph_name_index--;
        }

        /* length byte */
        pstr->size = (int)(*pascal_stringp);

        /* + 1 is for the length byte */
        pstr->data = pascal_stringp + 1;

        /* sanity check */
        if ( pstr->data + pstr->size > postp + table_length || pstr->data - 1 < postp)
            return gs_throw(-1, "data out of range");

        /* sigh - we have to allocate a copy of the data - by the
         * time a high level device makes use of it the font data
         * may be freed. This is a necessary leak. */
        mydata = gs_alloc_bytes(pfont->memory, pstr->size + 1, "glyph to name");
        if ( mydata == 0 )
            return -1;
        memcpy(mydata, pascal_stringp + 1, pstr->size);
        pstr->data = mydata;

        mydata[pstr->size] = 0;

        return 0;
    }
}
Exemplo n.º 19
0
int
gslt_measure_font_glyph(gs_state *pgs, gslt_font_t *xf, int gid, gslt_glyph_metrics_t *mtx)
{
    int head, format, loca, glyf;
    int ofs, len;
    int idx, i, n;
    int hadv, vadv, vorg;
    int vtop, ymax, desc;
    int scale;

    /* some insane defaults */

    scale = 2048; /* units-per-em */
    mtx->hadv = 0.5;
    mtx->vadv = -1.0;
    mtx->vorg = 1.0;

    /*
     * Horizontal metrics are easy.
     */

    ofs = gslt_find_sfnt_table(xf, "hhea", &len);
    if (ofs < 0)
	return gs_throw(-1, "cannot find hhea table");

    if (len < 2 * 18)
	return gs_throw(-1, "hhea table is too short");

    vorg = s16(xf->data + ofs + 4); /* ascender is default vorg */
    desc = s16(xf->data + ofs + 6); /* descender */
    if (desc < 0)
	desc = -desc;
    n = u16(xf->data + ofs + 17 * 2);

    ofs = gslt_find_sfnt_table(xf, "hmtx", &len);
    if (ofs < 0)
	return gs_throw(-1, "cannot find hmtx table");

    idx = gid;
    if (idx > n - 1)
	idx = n - 1;

    hadv = u16(xf->data + ofs + idx * 4);
    vadv = 0;

    /*
     * Vertical metrics are hairy (with missing tables).
     */

    head = gslt_find_sfnt_table(xf, "head", &len);
    if (head > 0)
    {
	scale = u16(xf->data + head + 18); /* units per em */
    }

    ofs = gslt_find_sfnt_table(xf, "OS/2", &len);
    if (ofs > 0 && len > 70)
    {
	vorg = s16(xf->data + ofs + 68); /* sTypoAscender */
	desc = s16(xf->data + ofs + 70); /* sTypoDescender */
	if (desc < 0)
	    desc = -desc;
    }

    ofs = gslt_find_sfnt_table(xf, "vhea", &len);
    if (ofs > 0)
    {
	if (len < 2 * 18)
	    return gs_throw(-1, "vhea table is too short");

	n = u16(xf->data + ofs + 17 * 2);

	ofs = gslt_find_sfnt_table(xf, "vmtx", &len);
	if (ofs < 0)
	    return gs_throw(-1, "cannot find vmtx table");

	idx = gid;
	if (idx > n - 1)
	    idx = n - 1;

	vadv = u16(xf->data + ofs + idx * 4);
	vtop = u16(xf->data + ofs + idx * 4 + 2);

	glyf = gslt_find_sfnt_table(xf, "glyf", &len);
	loca = gslt_find_sfnt_table(xf, "loca", &len);
	if (head > 0 && glyf > 0 && loca > 0)
	{
	    format = u16(xf->data + head + 50); /* indexToLocaFormat */

	    if (format == 0)
		ofs = u16(xf->data + loca + gid * 2) * 2;
	    else
		ofs = u32(xf->data + loca + gid * 4);

	    ymax = u16(xf->data + glyf + ofs + 8); /* yMax */

	    vorg = ymax + vtop;
	}
    }

    ofs = gslt_find_sfnt_table(xf, "VORG", &len);
    if (ofs > 0)
    {
	vorg = u16(xf->data + ofs + 6);
	n = u16(xf->data + ofs + 6);
	for (i = 0; i < n; i++)
	{
	    if (u16(xf->data + ofs + 8 + 4 * i) == gid)
	    {
		vorg = s16(xf->data + ofs + 8 + 4 * i + 2);
		break;
	    }
	}
    }

    if (vadv == 0)
	vadv = vorg + desc;

    mtx->hadv = hadv / (float) scale;
    mtx->vadv = vadv / (float) scale;
    mtx->vorg = vorg / (float) scale;

    return 0;
}
Exemplo n.º 20
0
int
xps_decode_jpegxr(xps_context_t *ctx, byte *buf, int len, xps_image_t *output)
{
    FILE *file;
    char *name = xps_alloc(ctx, gp_file_name_sizeof);
    struct state state;
    jxr_container_t container;
    jxr_image_t image;
    int offset, alpha_offset;
    int rc;

    if (!name) {
        return gs_throw(gs_error_VMerror, "cannot allocate scratch file name buffer");
    }

    memset(output, 0, sizeof(*output));

    file = gp_open_scratch_file(ctx->memory, "jpegxr-scratch-", name, "wb+");
    if (!file) {
        xps_free(ctx, name);
        return gs_throw(gs_error_invalidfileaccess, "cannot open scratch file");
    }
    rc = fwrite(buf, 1, len, file);
    if (rc != len) {
        xps_free(ctx, name);
        return gs_throw(gs_error_invalidfileaccess, "cannot write to scratch file");
    }
    fseek(file, 0, SEEK_SET);

    container = jxr_create_container();
    rc = jxr_read_image_container(container, file);
    if (rc < 0) {
        xps_free(ctx, name);
        return gs_throw1(-1, "jxr_read_image_container: %s", jxr_error_string(rc));
    }

    offset = jxrc_image_offset(container, 0);
    alpha_offset = jxrc_alpha_offset(container, 0);

    output->xres = jxrc_width_resolution(container, 0);
    output->yres = jxrc_height_resolution(container, 0);

    image = jxr_create_input();
    jxr_set_PROFILE_IDC(image, 111);
    jxr_set_LEVEL_IDC(image, 255);
    jxr_set_pixel_format(image, jxrc_image_pixelformat(container, 0));
    jxr_set_container_parameters(image,
        jxrc_image_pixelformat(container, 0),
        jxrc_image_width(container, 0),
        jxrc_image_height(container, 0),
        jxrc_alpha_offset(container, 0),
        jxrc_image_band_presence(container, 0),
        jxrc_alpha_band_presence(container, 0), 0);

    jxr_set_block_output(image, xps_decode_jpegxr_block);
    state.ctx = ctx;
    state.output = output;
    jxr_set_user_data(image, &state);

    fseek(file, offset, SEEK_SET);
    rc = jxr_read_image_bitstream(image, file);
    if (rc < 0) {
        xps_free(ctx, name);
        return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc));
    }

    jxr_destroy(image);

    if (alpha_offset > 0)
    {
        image = jxr_create_input();
        jxr_set_PROFILE_IDC(image, 111);
        jxr_set_LEVEL_IDC(image, 255);
        jxr_set_pixel_format(image, jxrc_image_pixelformat(container, 0));
        jxr_set_container_parameters(image,
            jxrc_image_pixelformat(container, 0),
            jxrc_image_width(container, 0),
            jxrc_image_height(container, 0),
            jxrc_alpha_offset(container, 0),
            jxrc_image_band_presence(container, 0),
            jxrc_alpha_band_presence(container, 0), 0);

        jxr_set_block_output(image, xps_decode_jpegxr_alpha_block);
        state.ctx = ctx;
        state.output = output;
        jxr_set_user_data(image, &state);

        fseek(file, alpha_offset, SEEK_SET);
        rc = jxr_read_image_bitstream(image, file);
        if (rc < 0) {
            xps_free(ctx, name);
            return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc));
        }

        jxr_destroy(image);
    }

    jxr_destroy_container(container);

    fclose(file);
    unlink(name);
    xps_free(ctx, name);

    return gs_okay;
}
Exemplo n.º 21
0
int
gslt_render_font_glyph(gs_state *pgs, gslt_font_t *xf, gs_matrix *tm, int gid, gslt_glyph_bitmap_t *slot)
{
    gs_fixed_point subpixel = {0, 0}; /* we don't use subpixel accurate device metrics */
    gs_log2_scale_point oversampling = {0, 0}; /* we don't use oversampling */
    gs_text_params_t params;
    gs_text_enum_t *textenum;
    gs_matrix matrix;
    cached_fm_pair *ppair;
    cached_char *cc;
    int code;

    /* get the real font matrix (this is a little dance) */
    gs_setfont(pgs, xf->font); /* set pgs->font and invalidate existing charmatrix */
    gs_setcharmatrix(pgs, tm); /* set the charmatrix to ctm * tm */
    gs_currentcharmatrix(pgs, &matrix, true); /* extract charmatrix (and multiply by FontMatrix) */

    // dprintf4("tm = [%g %g %g %g]\n", matrix.xx, matrix.xy, matrix.yx, matrix.yy);

    /* find the font/matrix pair (or add it) */
    code = gx_lookup_fm_pair(xf->font, &matrix, &oversampling, false, &ppair);
    if (code != 0)
        return gs_throw(-1, "cannot gx_lookup_fm_pair()");

    cc = gx_lookup_cached_char(xf->font, ppair, gid, 0, 1, &subpixel);
    if (!cc)
    {
        /* No luck ... now we need to get it into the cache somehow.
         *
         * We do this by rendering one glyph (that's why we need a device and pgs).
         * The renderer always renders the bitmap into the cache, and draws
         * from out of the cache when blitting to the device.
         *
         * Things don't get evicted from the cache until there is a collision,
         * so we have a safe window to snarf it back out of the cache
         * after it's been drawn to the device.
         */

        // dprintf1("cache miss for glyph %d\n", gid);

        params.operation = TEXT_FROM_SINGLE_GLYPH | TEXT_DO_DRAW | TEXT_RETURN_WIDTH;
        params.data.d_glyph = gid;
        params.size = 1;

	gs_moveto(pgs, 100.0, 100.0); // why?

        code = gs_text_begin(pgs, &params, xf->font->memory, &textenum);
	if (code != 0)
            return gs_throw1(-1, "cannot gs_text_begin() (%d)", code);

        code = gs_text_process(textenum);
	if (code != 0)
            return gs_throw1(-1, "cannot gs_text_process() (%d)", code);

        gs_text_release(textenum, "gslt font render");

        cc = gx_lookup_cached_char(xf->font, ppair, gid, 0, 1, &subpixel);
        if (!cc)
        {
            /* merde! it rendered but was not placed in the cache. */
            return gs_throw(-2, "cannot render from cache");
        }
    }

    /* copy values from the cache into the client struct */
    slot->w = cc->width;
    slot->h = cc->height;
    slot->stride = cc_raster(cc);
    slot->lsb = fixed2int(cc->offset.x);
    slot->top = fixed2int(cc->offset.y);

    slot->cc = cc;
    slot->data = cc_bits(cc);
    gx_retain_cached_char(cc);

#define XXX
#ifndef XXX
    static int xxx = 0; /* declaration out in the wild not allowed in ansi c */
    dprintf1("glyph %d\n", xxx);
    debug_dump_bitmap(cc_bits(cc), cc_raster(cc), cc->height, "");
    {
        char fn[32];
        sprintf(fn, "glyph%d.pbm", xxx);
        FILE *fo = fopen(fn, "wb");
        if (!fo)
            return -1;
        fprintf(fo, "P4\n%d %d\n", cc->width, cc->height);
        int y;
        int s = (cc->width + 7) / 8;
        for (y = 0; y < cc->height; y++)
            fwrite(cc_bits(cc) + y * cc_raster(cc), 1, s, fo);
        fclose(fo);
    }
    xxx ++;
#endif

    return 0;
}
Exemplo n.º 22
0
int
main(int argc, const char *argv[])
{
    gs_memory_t *mem;
    gx_device *dev;
    gs_state *pgs;
    gs_font_dir *cache;
    gslt_font_t *font;
    gslt_outline_walker_t walk;
    gslt_glyph_bitmap_t slot;
    gslt_glyph_metrics_t mtx;
    gs_matrix ctm;
    int code;
    char *s;
    char *devicename;
    char *filename;
    int i, k, n, pid, eid, best;
    int subfontid;
    char *buf;
    int len;

    char *text;

    devicename = getenv("DEVICE");
    if (!devicename)
        devicename = "nullpage";

    mem = gslt_init_library();
    dev = gslt_init_device(mem, devicename);
    pgs = gslt_init_state(mem, dev);

    if (argc < 2)
    {
        filename = "/Users/tor/src/work/gslite/TrajanPro-Regular.otf";
	// filename = "/Users/tor/src/work/gslite/GenR102.TTF";
	// return gs_throw(1, "usage: gslt_font_api_test font.otf [subfontid]");
    }
    else
    {
        filename = argv[1];
    }

    subfontid = 0;
    if (argc == 3)
	subfontid = atoi(argv[2]);

    printf("Loading font '%s' subfont %d.\n", filename, subfontid);

    n = readfile(filename, &buf, &len);
    if (n < 0) {
        printf("cannot read font file '%s'", filename);
	return 1;
    }

    /*
     * Set up ghostscript library
     */

    // gslt_get_device_param(mem, dev, "Name");
    gslt_set_device_param(mem, dev, "OutputFile", "-");


    /*
     * Create a font cache
     */

    cache = gslt_new_font_cache(mem);
    if (!cache) {
        printf("cannot create font cache\n");
	return 1;
    }

    /*
     * Create the font and select an encoding
     */

    font = gslt_new_font(mem, cache, buf, len, subfontid);
    if (!font) {
        printf("cannot create font");
	return 1;
    }

    static struct { int pid, eid; } xps_cmap_list[] =
    {
	{ 3, 10 },	/* Unicode with surrogates */
	{ 3, 1 },	/* Unicode without surrogates */
	{ 3, 5 },	/* Wansung */
	{ 3, 4 },	/* Big5 */
	{ 3, 3 },	/* Prc */
	{ 3, 2 },	/* ShiftJis */
	{ 3, 0 },	/* Symbol */
	// { 0, * }, -- Unicode (deprecated)
	{ 1, 0 },
	{ -1, -1 },
    };

    n = gslt_count_font_encodings(font);
    best = -1;
    for (k = 0; xps_cmap_list[k].pid != -1; k++)
    {
	for (i = 0; i < n; i++)
	{
	    gslt_identify_font_encoding(font, i, &pid, &eid);
	    if (pid == xps_cmap_list[k].pid && eid == xps_cmap_list[k].eid)
		goto found_cmap;
	}
    }
    gs_throw(-1, "could not find a suitable cmap");
    return 1;

found_cmap:
    printf("found a cmap to use %d %d\n", pid, eid);
    gslt_select_font_encoding(font, i);

    /*
     * Test outline extraction.
     */

    printf("walking the outline\n");

    walk.user = NULL;
    walk.moveto = mymoveto;
    walk.lineto = mylineto;
    walk.curveto = mycurveto;
    walk.closepath = myclosepath;

    code = gslt_outline_font_glyph(pgs, font, gslt_encode_font_char(font, 'I'), &walk);
    if (code < 0)
        printf("error in gslt_outline_font_glyph\n");

    /*
     * Test bitmap rendering.
     */
    
    printf("getting bitmaps\n");

    text = "Pack my box with five dozen liquor jugs!";

text = "This";

    ctm.xx = 100.0;
    ctm.xy = 0.0;
    ctm.yx = 0.0;
    ctm.yy = 100.0;
    ctm.tx = ctm.ty = 0.0;

    for (s = text; *s; s++)
    {
        int gid = gslt_encode_font_char(font, *s);

	if (s == text)
	    gid = 2119;

	printf("char '%c' -> glyph %d\n", *s, gid);

        code = gslt_measure_font_glyph(pgs, font, gid, &mtx);
        if (code < 0)
        {
            printf("error in gslt_measure_font_glyph\n");
        }

        printf("glyph %3d: hadv=%f vadv=%f vorg=%f ", gid, mtx.hadv, mtx.vadv, mtx.vorg);

        code = gslt_render_font_glyph(pgs, font, &ctm, gid, &slot);
        if (code < 0)
        {
            printf("error in gslt_render_font_glyph\n");
	    return 1;
        }

        printf(" -> %dx%d+(%d,%d)\n",
                slot.w, slot.h,
                slot.lsb, slot.top);

	gslt_release_font_glyph(mem, &slot);
    }

    /*
     * Clean up.
     */
    gslt_free_font(mem, font);
    gslt_free_font_cache(mem, cache);
    free(buf);

    gslt_free_state(mem, pgs);
    gslt_free_device(mem, dev);
    gslt_free_library(mem);

    gslt_alloc_print_leaks();

    return 0;
}
Exemplo n.º 23
0
static void
on_open_tag(void *zp, const char *ns_name, const char **atts)
{
    xps_parser_t *parser = zp;
    xps_context_t *ctx = parser->ctx;
    xps_item_t *item;
    xps_item_t *tail;
    int namelen;
    int attslen;
    int textlen;
    const char *name;
    char *p;
    int i;

    if (parser->error)
        return;

    /* check namespace */

    name = NULL;

    p = strstr(ns_name, NS_XPS);
    if (p == ns_name)
    {
        name = strchr(ns_name, ' ') + 1;
    }

    p = strstr(ns_name, NS_MC);
    if (p == ns_name)
    {
        name = strchr(ns_name, ' ') + 1;
    }

    p = strstr(ns_name, NS_OXPS);
    if (p == ns_name)
    {
        name = strchr(ns_name, ' ') + 1;
    }

    if (!name)
    {
        dmprintf1(ctx->memory, "unknown namespace: %s\n", ns_name);
        name = ns_name;
    }

    /* count size to alloc */

    namelen = strlen(name) + 1; /* zero terminated */
    attslen = sizeof(char*); /* with space for sentinel */
    textlen = 0;
    for (i = 0; atts[i]; i++)
    {
        attslen += sizeof(char*);
        if ((i & 1) == 0)
            textlen += strlen(skip_namespace(atts[i])) + 1;
        else
            textlen += strlen(atts[i]) + 1;
    }

    item = xps_alloc(ctx, sizeof(xps_item_t) + attslen + namelen + textlen);
    if (!item) {
        parser->error = "out of memory";
        gs_throw(gs_error_VMerror, "out of memory.\n");
        return;
    }

    /* copy strings to new memory */

    item->atts = (char**) (((char*)item) + sizeof(xps_item_t));
    item->name = ((char*)item) + sizeof(xps_item_t) + attslen;
    p = ((char*)item) + sizeof(xps_item_t) + attslen + namelen;

    strcpy(item->name, name);
    for (i = 0; atts[i]; i++)
    {
        item->atts[i] = p;
        if ((i & 1) == 0)
            strcpy(item->atts[i], skip_namespace(atts[i]));
        else
            strcpy(item->atts[i], atts[i]);
        p += strlen(p) + 1;
    }

    item->atts[i] = 0;

    /* link item into tree */

    item->up = parser->head;
    item->down = NULL;
    item->next = NULL;

    if (!parser->head)
    {
        parser->root = item;
        parser->head = item;
        return;
    }

    if (!parser->head->down)
    {
        parser->head->down = item;
        parser->head->tail = item;
        parser->head = item;
        return;
    }

    tail = parser->head->tail;
    tail->next = item;
    parser->head->tail = item;
    parser->head = item;
}
Exemplo n.º 24
0
int
gslt_outline_font_glyph(gs_state *pgs, gslt_font_t *xf, int gid, gslt_outline_walker_t *walk)
{
    gs_text_params_t params;
    gs_text_enum_t *textenum;
    gs_matrix matrix;
    segment *seg;
    curve_segment *cseg;

    gs_gsave(pgs);
    gs_make_identity(&matrix);
    gs_setmatrix(pgs, &matrix);
    gs_scale(pgs, 1000.0, 1000.0); /* otherwise we hit serious precision problems with fixpoint math */

    /* set gstate params */
    gs_setfont(pgs, xf->font); /* set pgs->font and invalidate existing charmatrix */
    gs_make_identity(&matrix);
    gs_setcharmatrix(pgs, &matrix); /* set the charmatrix to identity */

    /* reset the path */
    gs_newpath(pgs);
    gs_moveto(pgs, 0.0, 0.0);

    /* draw the glyph, in charpath mode */
    params.operation = TEXT_FROM_SINGLE_GLYPH | TEXT_DO_FALSE_CHARPATH | TEXT_RETURN_WIDTH;
    params.data.d_glyph = gid;
    params.size = 1;

    if (gs_text_begin(pgs, &params, xf->font->memory, &textenum) != 0)
        return gs_throw(-1, "cannot gs_text_begin()");
    if (gs_text_process(textenum) != 0)
        return gs_throw(-1, "cannot gs_text_process()");
    gs_text_release(textenum, "gslt font outline");

    /* walk the resulting path */
    seg = (segment*)pgs->path->first_subpath;
    while (seg)
    {
        switch (seg->type)
        {
        case s_start:
            walk->moveto(walk->user,
                    fixed2float(seg->pt.x) * 0.001,
                    fixed2float(seg->pt.y) * 0.001);
            break;
        case s_line:
            walk->lineto(walk->user,
                    fixed2float(seg->pt.x) * 0.001,
                    fixed2float(seg->pt.y) * 0.001);
            break;
        case s_line_close:
            walk->closepath(walk->user);
            break;
        case s_curve:
            cseg = (curve_segment*)seg;
            walk->curveto(walk->user,
                    fixed2float(cseg->p1.x) * 0.001,
                    fixed2float(cseg->p1.y) * 0.001,
                    fixed2float(cseg->p2.x) * 0.001,
                    fixed2float(cseg->p2.y) * 0.001,
                    fixed2float(seg->pt.x) * 0.001,
                    fixed2float(seg->pt.y) * 0.001);
            break;
        }
        seg = seg->next;
    }

    /* and toss it away... */
    gs_newpath(pgs);

    gs_grestore(pgs);
    return 0;
}
Exemplo n.º 25
0
/* (de)crypt a section of text--the procedure is the same
 * in each direction. see strimpl.h for return codes.
 */
static int
s_aes_process(stream_state * ss, stream_cursor_read * pr,
                  stream_cursor_write * pw, bool last)
{
    stream_aes_state *const state = (stream_aes_state *) ss;
    const unsigned char *limit;
    const long in_size = pr->limit - pr->ptr;
    const long out_size = pw->limit - pw->ptr;
    unsigned char temp[16];
    int status = 0;

    /* figure out if we're going to run out of space */
    if (in_size > out_size) {
        limit = pr->ptr + out_size;
        status = 1; /* need more output space */
    } else {
        limit = pr->limit;
        status = last ? EOFC : 0; /* need more input */
    }

    /* set up state and context */
    if (state->ctx == NULL) {
      /* allocate the aes context. this is a public struct but it
         contains internal pointers, so we need to store it separately
         in immovable memory like any opaque structure. */
      state->ctx = (aes_context *)gs_alloc_bytes_immovable(state->memory,
                sizeof(aes_context), "aes context structure");
      if (state->ctx == NULL) {
        gs_throw(gs_error_VMerror, "could not allocate aes context");
        return ERRC;
      }
      if (state->keylength < 1 || state->keylength > SAES_MAX_KEYLENGTH) {
        gs_throw1(gs_error_rangecheck, "invalid aes key length (%d bytes)",
                state->keylength);
        return ERRC;
      }
      aes_setkey_dec(state->ctx, state->key, state->keylength * 8);
    }
    if (!state->initialized) {
        /* read the initialization vector from the first 16 bytes */
        if (in_size < 16) return 0; /* get more data */
        memcpy(state->iv, pr->ptr + 1, 16);
        state->initialized = 1;
        pr->ptr += 16;
    }

    /* decrypt available blocks */
    while (pr->ptr + 16 <= limit) {
      aes_crypt_cbc(state->ctx, AES_DECRYPT, 16, state->iv,
                                pr->ptr + 1, temp);
      pr->ptr += 16;
      if (last && pr->ptr == pr->limit) {
        /* we're on the last block; unpad if necessary */
        int pad;

        if (state->use_padding) {
          /* we are using RFC 1423-style padding, so the last byte of the
             plaintext gives the number of bytes to discard */
          pad = temp[15];
          if (pad < 1 || pad > 16) {
            gs_throw1(gs_error_rangecheck, "invalid aes padding byte (0x%02x)",
                  (unsigned char)pad);
            return ERRC;
          }
        } else {
          /* not using padding */
          pad = 0;
        }

        memcpy(pw->ptr + 1, temp, 16 - pad);
        pw->ptr +=  16 - pad;
        return EOFC;
      }
      memcpy(pw->ptr + 1, temp, 16);
      pw->ptr += 16;
    }

    /* if we got to the end of the file without triggering the padding
       check, the input must not have been a multiple of 16 bytes long.
       complain. */
    if (status == EOFC) {
      gs_throw(gs_error_rangecheck, "aes stream isn't a multiple of 16 bytes");
      return ERRC;
    }

    return status;
}
Exemplo n.º 26
0
/*
 * To device space
 */
int
gx_remap_ICC(const gs_client_color * pcc, const gs_color_space * pcs,
        gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
                gs_color_select_t select)
{
    gsicc_link_t *icc_link;
    gsicc_rendering_param_t rendering_params;
    unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS], psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
    unsigned short *psrc_temp;
    frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
    int k,i;
#ifdef DEBUG
    int num_src_comps;
#endif
    int num_des_comps;
    int code;
    cmm_dev_profile_t *dev_profile;

    code = dev_proc(dev, get_profile)(dev, &dev_profile);
    if (code < 0)
        return code;
    if (dev_profile == NULL)
        return gs_throw(gs_error_Fatal, "Attempting to do ICC remap with no profile");
    num_des_comps = gsicc_get_device_profile_comps(dev_profile);
    rendering_params.black_point_comp = pgs->blackptcomp;
    rendering_params.graphics_type_tag = dev->graphics_type_tag;
    rendering_params.override_icc = false;
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
    rendering_params.rendering_intent = pgs->renderingintent;
    rendering_params.cmm = gsCMM_DEFAULT;
    /* Need to clear out psrc_cm in case we have separation bands that are
       not color managed */
    memset(psrc_cm,0,sizeof(unsigned short)*GS_CLIENT_COLOR_MAX_COMPONENTS);

     /* This needs to be optimized */
    if (pcs->cmm_icc_profile_data->data_cs == gsCIELAB ||
        pcs->cmm_icc_profile_data->islab) {
        psrc[0] = (unsigned short) (pcc->paint.values[0]*65535.0/100.0);
        psrc[1] = (unsigned short) ((pcc->paint.values[1]+128)/255.0*65535.0);
        psrc[2] = (unsigned short) ((pcc->paint.values[2]+128)/255.0*65535.0);
    } else {
        for (k = 0; k < pcs->cmm_icc_profile_data->num_comps; k++){
            psrc[k] = (unsigned short) (pcc->paint.values[k]*65535.0);
        }
    }
    /* Get a link from the cache, or create if it is not there. Need to get 16 bit profile */
    icc_link = gsicc_get_link(pgs, dev, pcs, NULL, &rendering_params, pgs->memory);
    if (icc_link == NULL) {
        #ifdef DEBUG
            gs_warn("Could not create ICC link:  Check profiles");
        #endif
        return -1;
    }
    if (icc_link->is_identity) {
        psrc_temp = &(psrc[0]);
    } else {
        /* Transform the color */
        psrc_temp = &(psrc_cm[0]);
        (icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2);
    }
#ifdef DEBUG
    if (!icc_link->is_identity) {
        num_src_comps = pcs->cmm_icc_profile_data->num_comps;
        if_debug0m(gs_debug_flag_icc, dev->memory, "[icc] remap [ ");
        for (k = 0; k < num_src_comps; k++) {
            if_debug1m(gs_debug_flag_icc, dev->memory, "%d ", psrc[k]);
        }
        if_debug0m(gs_debug_flag_icc, dev->memory, "] --> [ ");
        for (k = 0; k < num_des_comps; k++) {
            if_debug1m(gs_debug_flag_icc, dev->memory, "%d ", psrc_temp[k]);
        }
        if_debug0m(gs_debug_flag_icc, dev->memory, "]\n");
    }
#endif
    /* Release the link */
    gsicc_release_link(icc_link);
    /* Now do the remap for ICC which amounts to the alpha application
       the transfer function and potentially the halftoning */
    /* Right now we need to go from unsigned short to frac.  I really
       would like to avoid this sort of stuff.  That will come. */
    for ( k = 0; k < num_des_comps; k++){
        conc[k] = ushort2frac(psrc_temp[k]);
    }
    gx_remap_concrete_ICC(conc, pcs, pdc, pgs, dev, select);

    /* Save original color space and color info into dev color */
    i = pcs->cmm_icc_profile_data->num_comps;
    for (i--; i >= 0; i--)
        pdc->ccolor.paint.values[i] = pcc->paint.values[i];
    pdc->ccolor_valid = true;
    return 0;
}
Exemplo n.º 27
0
int
xps_decode_jpeg(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
{
    jpeg_decompress_data jddp;
    stream_DCT_state state;
    stream_cursor_read rp;
    stream_cursor_write wp;
    int code;
    int wlen;
    byte *wbuf;
    jpeg_saved_marker_ptr curr_marker;

    s_init_state((stream_state*)&state, &s_DCTD_template, ctx->memory);
    state.report_error = xps_report_error;

    s_DCTD_template.set_defaults((stream_state*)&state);

    state.jpeg_memory = ctx->memory;
    state.data.decompress = &jddp;

    jddp.templat = s_DCTD_template;
    jddp.memory = ctx->memory;
    jddp.scanline_buffer = NULL;

    if ((code = gs_jpeg_create_decompress(&state)) < 0)
        return gs_throw(-1, "cannot gs_jpeg_create_decompress");

    s_DCTD_template.init((stream_state*)&state);

    rp.ptr = rbuf - 1;
    rp.limit = rbuf + rlen - 1;

    /* read the header only by not having a write buffer */
    wp.ptr = 0;
    wp.limit = 0;

    /* Set up to save the ICC marker APP2.
     * According to the spec we should be getting APP1 APP2 and APP13.
     * Library gets APP0 and APP14. */
    jpeg_save_markers(&(jddp.dinfo), 0xe2, 0xFFFF);

    code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
    if (code != 1)
        return gs_throw(-1, "premature EOF or error in jpeg");

    /* Check if we had an ICC profile */
    curr_marker = jddp.dinfo.marker_list;
    while (curr_marker != NULL)
    {
        if (curr_marker->marker == 0xe2)
        {
            /* Found ICC profile. Create a buffer and copy over now.
             * Strip JPEG APP2 14 byte header */
            image->profilesize = curr_marker->data_length - 14;
            image->profile = xps_alloc(ctx, image->profilesize);
            if (image->profile)
            {
                /* If we can't create it, just ignore */
                memcpy(image->profile, &(curr_marker->data[14]), image->profilesize);
            }
            break;
        }
        curr_marker = curr_marker->next;
    }

    image->width = jddp.dinfo.output_width;
    image->height = jddp.dinfo.output_height;
    image->comps = jddp.dinfo.output_components;
    image->bits = 8;
    image->stride = image->width * image->comps;

    if (image->comps == 1)
        image->colorspace = ctx->gray;
    if (image->comps == 3)
        image->colorspace = ctx->srgb;
    if (image->comps == 4)
        image->colorspace = ctx->cmyk;

    if (jddp.dinfo.density_unit == 1)
    {
        image->xres = jddp.dinfo.X_density;
        image->yres = jddp.dinfo.Y_density;
    }
    else if (jddp.dinfo.density_unit == 2)
    {
        image->xres = (int)(jddp.dinfo.X_density * 2.54 + 0.5);
        image->yres = (int)(jddp.dinfo.Y_density * 2.54 + 0.5);
    }
    else
    {
        image->xres = 96;
        image->yres = 96;
    }

    wlen = image->stride * image->height;
    wbuf = xps_alloc(ctx, wlen);
    if (!wbuf)
        return gs_throw1(gs_error_VMerror, "out of memory allocating samples: %d", wlen);

    image->samples = wbuf;

    wp.ptr = wbuf - 1;
    wp.limit = wbuf + wlen - 1;

    code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
    if (code != EOFC)
        return gs_throw1(-1, "error in jpeg (code = %d)", code);

    gs_jpeg_destroy(&state);

    return gs_okay;
}
Exemplo n.º 28
0
int
xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part)
{
    xps_item_t *root, *node;
    xps_resource_t *dict;
    char *width_att;
    char *height_att;
    char base_uri[1024];
    char *s;
    int code;

    if_debug1m('|', ctx->memory, "doc: parsing page %s\n", part->name);

    xps_strlcpy(base_uri, part->name, sizeof base_uri);
    s = strrchr(base_uri, '/');
    if (s)
        s[1] = 0;

    root = xps_parse_xml(ctx, part->data, part->size);
    if (!root)
        return gs_rethrow(-1, "cannot parse xml");

    if (strcmp(xps_tag(root), "FixedPage"))
        return gs_throw1(-1, "expected FixedPage element (found %s)", xps_tag(root));

    width_att = xps_att(root, "Width");
    height_att = xps_att(root, "Height");

    if (!width_att)
        return gs_throw(-1, "FixedPage missing required attribute: Width");
    if (!height_att)
        return gs_throw(-1, "FixedPage missing required attribute: Height");

    dict = NULL;

    /* Setup new page */
    {
        gs_memory_t *mem = ctx->memory;
        gs_state *pgs = ctx->pgs;
        gx_device *dev = gs_currentdevice(pgs);
        gs_param_float_array fa;
        float fv[2];
        gs_c_param_list list;

        gs_c_param_list_write(&list, mem);

        fv[0] = atoi(width_att) / 96.0 * 72.0;
        fv[1] = atoi(height_att) / 96.0 * 72.0;
        fa.persistent = false;
        fa.data = fv;
        fa.size = 2;

        code = param_write_float_array((gs_param_list *)&list, ".MediaSize", &fa);
        if ( code >= 0 )
        {
            gs_c_param_list_read(&list);
            code = gs_putdeviceparams(dev, (gs_param_list *)&list);
        }
        gs_c_param_list_release(&list);

        /* nb this is for the demo it is wrong and should be removed */
        gs_initgraphics(pgs);

        /* 96 dpi default - and put the origin at the top of the page */

        gs_initmatrix(pgs);

        code = gs_scale(pgs, 72.0/96.0, -72.0/96.0);
        if (code < 0)
            return gs_rethrow(code, "cannot set page transform");

        code = gs_translate(pgs, 0.0, -atoi(height_att));
        if (code < 0)
            return gs_rethrow(code, "cannot set page transform");

        code = gs_erasepage(pgs);
        if (code < 0)
            return gs_rethrow(code, "cannot clear page");
    }

    /* Pre-parse looking for transparency */

    ctx->has_transparency = 0;

    for (node = xps_down(root); node; node = xps_next(node))
    {
        if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node))
            if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node)))
                ctx->has_transparency = 1;
        if (xps_element_has_transparency(ctx, base_uri, node))
            ctx->has_transparency = 1;
    }

    /* save the state with the original device before we push */
    gs_gsave(ctx->pgs);

    if (ctx->use_transparency && ctx->has_transparency)
    {
        code = gs_push_pdf14trans_device(ctx->pgs, false);
        if (code < 0)
        {
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot install transparency device");
        }
    }

    /* Draw contents */

    for (node = xps_down(root); node; node = xps_next(node))
    {
        if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node))
        {
            code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xps_down(node));
            if (code)
            {
                gs_pop_pdf14trans_device(ctx->pgs, false);
                gs_grestore(ctx->pgs);
                return gs_rethrow(code, "cannot load FixedPage.Resources");
            }
        }
        code = xps_parse_element(ctx, base_uri, dict, node);
        if (code)
        {
            gs_pop_pdf14trans_device(ctx->pgs, false);
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot parse child of FixedPage");
        }
    }

    if (ctx->use_transparency && ctx->has_transparency)
    {
        code = gs_pop_pdf14trans_device(ctx->pgs, false);
        if (code < 0)
        {
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot uninstall transparency device");
        }
    }

    /* Flush page */
    {
        code = xps_show_page(ctx, 1, true); /* copies, flush */
        if (code < 0)
        {
            gs_grestore(ctx->pgs);
            return gs_rethrow(code, "cannot flush page");
        }
    }

    /* restore the original device, discarding the pdf14 compositor */
    gs_grestore(ctx->pgs);

    if (dict)
    {
        xps_free_resource_dictionary(ctx, dict);
    }

    xps_free_item(ctx, root);

    return 0;
}