Blame jbig2_metadata.c

Packit 3f21c4
/* Copyright (C) 2001-2012 Artifex Software, Inc.
Packit 3f21c4
   All Rights Reserved.
Packit 3f21c4
Packit 3f21c4
   This software is provided AS-IS with no warranty, either express or
Packit 3f21c4
   implied.
Packit 3f21c4
Packit 3f21c4
   This software is distributed under license and may not be copied,
Packit 3f21c4
   modified or distributed except as expressly authorized under the terms
Packit 3f21c4
   of the license contained in the file LICENSE in this distribution.
Packit 3f21c4
Packit 3f21c4
   Refer to licensing information at http://www.artifex.com or contact
Packit 3f21c4
   Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
Packit 3f21c4
   CA  94903, U.S.A., +1(415)492-9861, for further information.
Packit 3f21c4
*/
Packit 3f21c4
Packit 3f21c4
/*
Packit 3f21c4
    jbig2dec
Packit 3f21c4
*/
Packit 3f21c4
Packit 3f21c4
#ifdef HAVE_CONFIG_H
Packit 3f21c4
#include "config.h"
Packit 3f21c4
#endif
Packit 3f21c4
#include "os_types.h"
Packit 3f21c4
Packit 3f21c4
#include <stdlib.h>
Packit 3f21c4
#include <string.h>
Packit 3f21c4
Packit 3f21c4
#include "jbig2.h"
Packit 3f21c4
#include "jbig2_priv.h"
Packit 3f21c4
#include "jbig2_metadata.h"
Packit 3f21c4
Packit 3f21c4
/* metadata key,value list object */
Packit 3f21c4
Jbig2Metadata *
Packit 3f21c4
jbig2_metadata_new(Jbig2Ctx *ctx, Jbig2Encoding encoding)
Packit 3f21c4
{
Packit 3f21c4
    Jbig2Metadata *md = jbig2_new(ctx, Jbig2Metadata, 1);
Packit 3f21c4
Packit 3f21c4
    if (md != NULL) {
Packit 3f21c4
        md->encoding = encoding;
Packit 3f21c4
        md->entries = 0;
Packit 3f21c4
        md->max_entries = 4;
Packit 3f21c4
        md->keys = jbig2_new(ctx, char *, md->max_entries);
Packit 3f21c4
        md->values = jbig2_new(ctx, char *, md->max_entries);
Packit 3f21c4
Packit 3f21c4
        if (md->keys == NULL || md->values == NULL) {
Packit 3f21c4
            jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to allocate storage for metadata keys/values");
Packit 3f21c4
            jbig2_metadata_free(ctx, md);
Packit 3f21c4
            md = NULL;
Packit 3f21c4
        }
Packit 3f21c4
    } else {
Packit 3f21c4
        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "failed to allocate storage for metadata");
Packit 3f21c4
    }
Packit 3f21c4
    return md;
Packit 3f21c4
}
Packit 3f21c4
Packit 3f21c4
void
Packit 3f21c4
jbig2_metadata_free(Jbig2Ctx *ctx, Jbig2Metadata *md)
Packit 3f21c4
{
Packit 3f21c4
    int i;
Packit 3f21c4
Packit 3f21c4
    if (md->keys) {
Packit 3f21c4
        /* assume we own the pointers */
Packit 3f21c4
        for (i = 0; i < md->entries; i++)
Packit 3f21c4
            jbig2_free(ctx->allocator, md->keys[i]);
Packit 3f21c4
        jbig2_free(ctx->allocator, md->keys);
Packit 3f21c4
    }
Packit 3f21c4
    if (md->values) {
Packit 3f21c4
        for (i = 0; i < md->entries; i++)
Packit 3f21c4
            jbig2_free(ctx->allocator, md->values[i]);
Packit 3f21c4
        jbig2_free(ctx->allocator, md->values);
Packit 3f21c4
    }
Packit 3f21c4
    jbig2_free(ctx->allocator, md);
Packit 3f21c4
}
Packit 3f21c4
Packit 3f21c4
static char *
Packit 3f21c4
jbig2_strndup(Jbig2Ctx *ctx, const char *c, const int len)
Packit 3f21c4
{
Packit 3f21c4
    char *s = jbig2_new(ctx, char, len);
Packit 3f21c4
Packit 3f21c4
    if (s == NULL) {
Packit 3f21c4
        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "unable to duplicate comment string");
Packit 3f21c4
    } else {
Packit 3f21c4
        memcpy(s, c, len);
Packit 3f21c4
    }
Packit 3f21c4
    return s;
Packit 3f21c4
}
Packit 3f21c4
Packit 3f21c4
int
Packit 3f21c4
jbig2_metadata_add(Jbig2Ctx *ctx, Jbig2Metadata *md, const char *key, const int key_length, const char *value, const int value_length)
Packit 3f21c4
{
Packit 3f21c4
    char **keys, **values;
Packit 3f21c4
Packit 3f21c4
    /* grow the array if necessary */
Packit 3f21c4
    if (md->entries == md->max_entries) {
Packit 3f21c4
        md->max_entries <<= 1;
Packit 3f21c4
        keys = jbig2_renew(ctx, md->keys, char *, md->max_entries);
Packit 3f21c4
        values = jbig2_renew(ctx, md->values, char *, md->max_entries);
Packit 3f21c4
Packit 3f21c4
        if (keys == NULL || values == NULL) {
Packit 3f21c4
            jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "unable to resize metadata structure");
Packit 3f21c4
            return -1;
Packit 3f21c4
        }
Packit 3f21c4
        md->keys = keys;
Packit 3f21c4
        md->values = values;
Packit 3f21c4
    }
Packit 3f21c4
Packit 3f21c4
    /* copy the passed key,value pair */
Packit 3f21c4
    md->keys[md->entries] = jbig2_strndup(ctx, key, key_length);
Packit 3f21c4
    md->values[md->entries] = jbig2_strndup(ctx, value, value_length);
Packit 3f21c4
    md->entries++;
Packit 3f21c4
Packit 3f21c4
    return 0;
Packit 3f21c4
}
Packit 3f21c4
Packit 3f21c4
/* decode an ascii comment segment 7.4.15.1 */
Packit 3f21c4
int
Packit 3f21c4
jbig2_comment_ascii(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data)
Packit 3f21c4
{
Packit 3f21c4
    char *s = (char *)(segment_data + 4);
Packit 3f21c4
    char *end = (char *)(segment_data + segment->data_length);
Packit 3f21c4
    Jbig2Metadata *comment;
Packit 3f21c4
    char *key, *value;
Packit 3f21c4
Packit 3f21c4
    jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "ASCII comment data");
Packit 3f21c4
Packit 3f21c4
    comment = jbig2_metadata_new(ctx, JBIG2_ENCODING_ASCII);
Packit 3f21c4
    if (comment == NULL) {
Packit 3f21c4
        jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unable to allocate comment structure");
Packit 3f21c4
        return -1;
Packit 3f21c4
    }
Packit 3f21c4
    /* loop over the segment data pulling out the key,value pairs */
Packit 3f21c4
    while (s < end && *s) {
Packit 3f21c4
        key = s;
Packit 3f21c4
        value = memchr(key, '\0', end - key);
Packit 3f21c4
        if (!value)
Packit 3f21c4
            goto too_short;
Packit 3f21c4
        value++;
Packit 3f21c4
        s = memchr(value, '\0', end - value);
Packit 3f21c4
        if (!s)
Packit 3f21c4
            goto too_short;
Packit 3f21c4
        s++;
Packit 3f21c4
        jbig2_metadata_add(ctx, comment, key, value - key, value, s - value);
Packit 3f21c4
        jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "'%s'\t'%s'", key, value);
Packit 3f21c4
    }
Packit 3f21c4
Packit 3f21c4
    /* TODO: associate with ctx, page, or referred-to segment(s) */
Packit 3f21c4
    segment->result = comment;
Packit 3f21c4
Packit 3f21c4
    return 0;
Packit 3f21c4
Packit 3f21c4
too_short:
Packit 3f21c4
    jbig2_metadata_free(ctx, comment);
Packit 3f21c4
    return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unexpected end of comment segment");
Packit 3f21c4
}
Packit 3f21c4
Packit 3f21c4
/* decode a UCS-16 comment segement 7.4.15.2 */
Packit 3f21c4
int
Packit 3f21c4
jbig2_comment_unicode(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data)
Packit 3f21c4
{
Packit 3f21c4
    return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "unhandled unicode comment segment");
Packit 3f21c4
}