|
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 |
}
|