jbig2dec
Ralph Giles <[email protected]> Tue, 04 Mar 2003 18:44:46 -0800
| Newsgroups | gmane.comp.printing.ghostscript.jbig2dec.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/jbig2dec/jbig2dec
In directory sc8-pr-cvs1:/tmp/cvs-serv637
Modified Files:
Makefile.am jbig2_segment.c
Added Files:
jbig2_metadata.c jbig2_metadata.h
Log Message:
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.
--- NEW FILE: jbig2_metadata.c ---
/*
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");
}
--- NEW FILE: jbig2_metadata.h ---
/*
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 */
Index: Makefile.am
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/Makefile.am,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- Makefile.am 4 Mar 2003 16:52:47 -0000 1.14
+++ Makefile.am 5 Mar 2003 02:44:43 -0000 1.15
@@ -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
Index: jbig2_segment.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_segment.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- jbig2_segment.c 4 Mar 2003 17:29:24 -0000 1.20
+++ jbig2_segment.c 5 Mar 2003 02:44:43 -0000 1.21
@@ -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);