ref: 22881a46c322b45b34e20b9270e825dbe5c2c1a1
parent: 4f74ab25a2904a70c3e1e017090aed00cbd4cae3
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Tue Mar 4 21:44:43 EST 2003
Add support for ASCII-format comment extension segments. So far it's just useful for printing out the contents through the error callback; eventually there should be a public interface of the metadata tables and references from the associated ctx/page/segments. git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@218 ded80894-8fb9-0310-811b-c03f3676ab4d
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-# $Id: Makefile.am,v 1.14 2003/03/04 16:52:47 giles Exp $
+# $Id: Makefile.am,v 1.15 2003/03/05 02:44:43 giles Exp $
## process this file with automake to generate Makefile.in
AUTOMAKE_OPTIONS = foreign 1.7 dist-bzip2 # require automake 1.7
@@ -16,7 +16,8 @@
jbig2.h jbig2_priv.h jbig2_image.h \
jbig2_arith.h jbig2_arith_iaid.h jbig2_arith_int.h \
jbig2_huffman.h jbig2_hufftab.h jbig2_mmr.h \
- jbig2_generic.h jbig2_symbol_dict.h
+ jbig2_generic.h jbig2_symbol_dict.h \
+ jbig2_metadata.c jbig2_metadata.h
bin_PROGRAMS = jbig2dec
#noinst_PROGRAMS = test_huffman test_arith
--- /dev/null
+++ b/jbig2_metadata.c
@@ -1,0 +1,142 @@
+/*
+ jbig2dec
+
+ Copyright (c) 2001-2002 artofcode LLC.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ $Id: jbig2_metadata.c,v 1.1 2003/03/05 02:44:43 giles Exp $
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "os_types.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "jbig2.h"
+#include "jbig2_priv.h"
+#include "jbig2_metadata.h"
+
+/* metadata key,value list object */
+Jbig2Metadata *jbig2_metadata_new(Jbig2Ctx *ctx, Jbig2Encoding encoding)
+{
+ Jbig2Metadata *md = jbig2_alloc(ctx->allocator, sizeof(Jbig2Metadata));
+
+ if (md != NULL) {
+ md->encoding = encoding;
+ md->entries = 0;
+ md->max_entries = 4;
+ md->keys = jbig2_alloc(ctx->allocator, md->max_entries*sizeof(char*));
+ md->values = jbig2_alloc(ctx->allocator, md->max_entries*sizeof(char*));
+ if (md->keys == NULL || md->values == NULL) {
+ jbig2_metadata_free(ctx, md);
+ md = NULL;
+ }
+ }
+ return md;
+}
+
+void jbig2_metadata_free(Jbig2Ctx *ctx, Jbig2Metadata *md)
+{
+ if (md->keys) jbig2_free(ctx->allocator, md->keys);
+ if (md->values) jbig2_free(ctx->allocator, md->values);
+ jbig2_free(ctx->allocator, md);
+}
+
+static char *jbig2_strndup(Jbig2Ctx *ctx, const char *c, const int len)
+{
+ char *s = jbig2_alloc(ctx->allocator, len*sizeof(char));
+ if (s == NULL) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+ "unable to duplicate comment string");
+ } else {
+ memcpy(s, c, len);
+ }
+ return s;
+}
+
+int jbig2_metadata_add(Jbig2Ctx *ctx, Jbig2Metadata *md,
+ const char *key, const int key_length,
+ const char *value, const int value_length)
+{
+ char **keys, **values;
+
+ /* grow the array if necessary */
+ if (md->entries == md->max_entries) {
+ md->max_entries >>= 2;
+ keys = jbig2_realloc(ctx->allocator, md->keys, md->max_entries);
+ values = jbig2_realloc(ctx->allocator, md->values, md->max_entries);
+ if (keys == NULL || values == NULL) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+ "unable to resize metadata structure");
+ return -1;
+ }
+ md->keys = keys;
+ md->values = values;
+ }
+
+ /* copy the passed key,value pair */
+ md->keys[md->entries] = jbig2_strndup(ctx, key, key_length);
+ md->values[md->entries] = jbig2_strndup(ctx, value, value_length);
+ md->entries++;
+
+ return 0;
+}
+
+
+/* decode an ascii comment segment 7.4.15.1 */
+int jbig2_parse_comment_ascii(Jbig2Ctx *ctx, Jbig2Segment *segment,
+ const uint8_t *segment_data)
+{
+ char *s = (char *)segment_data + 4;
+ char *end = (char *)segment_data + segment->data_length;
+ Jbig2Metadata *comment;
+ char *key, *value;
+ int key_length, value_length;
+
+ jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
+ "ASCII comment data");
+
+ comment = jbig2_metadata_new(ctx, JBIG2_ENCODING_ASCII);
+ if (comment == NULL) {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "unable to allocate comment structure");
+ return -1;
+ }
+ /* loop over the segment data pulling out the key,value pairs */
+ while(*s && s < end) {
+ key_length = strlen(s) + 1;
+ key = s; s += key_length;
+ if (s >= end) goto too_short;
+ value_length = strlen(s) + 1;
+ value = s; s += value_length;
+ if (s >= end) goto too_short;
+ jbig2_metadata_add(ctx, comment, key, key_length, value, value_length);
+ jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
+ "'%s'\t'%s'", key, value);
+ }
+
+ /* TODO: associate with ctx, page, or referred-to segment(s) */
+ segment->result = comment;
+
+ return 0;
+
+too_short:
+ jbig2_metadata_free(ctx, comment);
+ return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "unexpected end of comment segment");
+}
+
+/* decode a UCS-16 comment segement 7.4.15.2 */
+int jbig2_parse_comment_unicode(Jbig2Ctx *ctx, Jbig2Segment *segment,
+ const uint8_t *segment_data)
+{
+ return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "unhandled unicode comment segment");
+}
--- /dev/null
+++ b/jbig2_metadata.h
@@ -1,0 +1,46 @@
+/*
+ jbig2dec
+
+ Copyright (c) 2001-2002 artofcode LLC.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ $Id: jbig2_metadata.h,v 1.1 2003/03/05 02:44:43 giles Exp $
+*/
+
+
+#ifndef _JBIG2_METADATA_H
+#define _JBIG2_METADATA_H
+
+/* metadata from extension segments */
+
+/* these bits should be moved to jbig2.h for public access */
+typedef enum {
+ JBIG2_ENCODING_ASCII,
+ JBIG2_ENCODING_UCS16
+} Jbig2Encoding;
+
+typedef struct _Jbig2Metadata Jbig2Metadata;
+
+Jbig2Metadata *jbig2_metadata_new(Jbig2Ctx *ctx, Jbig2Encoding encoding);
+void jbig2_metadata_free(Jbig2Ctx *ctx, Jbig2Metadata *md);
+int jbig2_metadata_add(Jbig2Ctx *ctx, Jbig2Metadata *md,
+ const char *key, const int key_length,
+ const char *value, const int value_length);
+
+struct _Jbig2Metadata {
+ Jbig2Encoding encoding;
+ char **keys, **values;
+ int entries, max_entries;
+};
+
+/* these bits can go to jbig2_priv.h */
+int jbig2_parse_comment_ascii(Jbig2Ctx *ctx, Jbig2Segment *segment,
+ const uint8_t *segment_data);
+int jbig2_parse_comment_unicode(Jbig2Ctx *ctx, Jbig2Segment *segment,
+ const uint8_t *segment_data);
+
+#endif /* _JBIG2_METADATA_H */
--- a/jbig2_segment.c
+++ b/jbig2_segment.c
@@ -8,7 +8,7 @@
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
- $Id: jbig2_segment.c,v 1.20 2003/03/04 17:29:24 giles Exp $
+ $Id: jbig2_segment.c,v 1.21 2003/03/05 02:44:43 giles Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -136,6 +136,39 @@
info->flags = segment_data[16];
}
+int jbig2_parse_extension_segment(Jbig2Ctx *ctx, Jbig2Segment *segment,
+ const uint8_t *segment_data)
+{
+ uint32_t type;
+ bool reserved, dependent, necessary;
+
+ type = jbig2_get_int32(segment_data);
+
+ reserved = type & 0x20000000;
+ dependent = type & 0x40000000;
+ necessary = type & 0x80000000;
+
+ if (necessary && !reserved) {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "extension segment is marked 'necessary' but not 'reservered' contrary to spec");
+ }
+
+ switch (type) {
+ case 0x20000000: return jbig2_parse_comment_ascii(ctx, segment, segment_data);
+ case 0x20000002: return jbig2_parse_comment_unicode(ctx, segment, segment_data);
+ default:
+ if (necessary) {
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+ "unhandled necessary extension segment type 0x%08x", type);
+ } else {
+ return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "unhandled extension segment");
+ }
+ }
+
+ return 0;
+}
+
int jbig2_parse_segment (Jbig2Ctx *ctx, Jbig2Segment *segment,
const uint8_t *segment_data)
{
@@ -198,8 +231,7 @@
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled table segment");
case 62:
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
- "unhandled extension segment");
+ return jbig2_parse_extension_segment(ctx, segment, segment_data);
default:
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unknown segment type %d", segment->flags & 63);