Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 8618 → Rev 8619

/contrib/sdk/sources/libjbig2dec/Makefile
0,0 → 1,18
CC = kos32-gcc
LD = kos32-ld
 
SDK_DIR = /media/maxim/E22406D62406AE1B/SVNKOS/contrib/sdk
CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32
 
INCLUDES = -I $(SDK_DIR)/sources/newlib/libc/include -I $(SDK_DIR)/sources/freetype/include -I $(SDK_DIR)/sources/libpng -I $(SDK_DIR)/sources/zlib -I .
 
SRC := $(notdir $(wildcard *.c))
OBJECTS = $(patsubst %.c, %.o, $(SRC))
 
default: $(patsubst %.c,%.o,$(SRC))
ar rcs libjbig2dec.a *.o
rm *.o
mv libjbig2dec.a ../../lib
 
%.o : %.c Makefile $(SRC)
$(CC) $(CFLAGS) -DHAVE_CONFIG_H $(INCLUDES) -o $@ $<
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/Tupfile.lua
0,0 → 1,10
if tup.getconfig("NO_GCC") ~= "" then return end
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../../../../programs" or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_gcc.lua")
tup.include(HELPERDIR .. "/use_newlib.lua")
CFLAGS = CFLAGS .. " -std=c99 -DHAVE_CONFIG_H"
INCLUDES = INCLUDES .. " -I ."
compile_gcc{"jbig2_arith.c", "jbig2_arith_iaid.c", "jbig2_arith_int.c", "jbig2.c", "jbig2dec.c", "jbig2_generic.c", "jbig2_halftone.c", "jbig2_huffman.c", "jbig2_image.c", "jbig2_image_pbm.c", "jbig2_metadata.c", "jbig2_mmr.c", "jbig2_page.c", "jbig2_refinement.c", "jbig2_segment.c", "jbig2_symbol_dict.c", "jbig2_text.c", "memcmp.c", "sha1.c"}
tup.rule(OBJS, "kos32-ar rcs %o %f", {"../../lib/libjbig2dec.a", "<../../lib/libjbig2dec>"})
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/config.h
0,0 → 1,120
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
 
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
 
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
 
/* Define if the local libc includes getopt_long() */
#define HAVE_GETOPT_LONG /**/
 
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
 
/* Define to 1 if you have the <libintl.h> header file. */
#define HAVE_LIBINTL_H 1
 
/* Define if libpng is available (-lpng) */
#define HAVE_LIBPNG 1
 
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
 
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
 
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
 
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
 
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
 
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
 
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
 
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
 
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
 
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
 
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
 
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
 
/* set by configure if an alternate header with the stdint.h types is found */
/* #undef JBIG2_REPLACE_STDINT_H */
 
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
 
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
 
/* Name of package */
#define PACKAGE "jbig2dec"
 
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "jbig2-dev@ghostscript.com"
 
/* Define to the full name of this package. */
#define PACKAGE_NAME "jbig2dec"
 
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "jbig2dec 0.11"
 
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "jbig2dec"
 
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.11"
 
/* The size of `char', as computed by sizeof. */
#define SIZEOF_CHAR 1
 
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
 
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG 4
 
/* The size of `short', as computed by sizeof. */
#define SIZEOF_SHORT 2
 
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
 
/* Version number of package */
#define VERSION "0.11"
 
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
 
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
 
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/config_types.h
0,0 → 1,19
/*
generated header with missing types for the
jbig2dec program and library. include this
after config.h, within the HAVE_CONFIG_H
ifdef
*/
 
#ifndef HAVE_STDINT_H
# ifdef JBIG2_REPLACE_STDINT_H
# include <no_replacement_found>
# else
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef signed int int32_t;
typedef signed short int16_t;
typedef signed char int8_t;
# endif /* JBIG2_REPLACE_STDINT */
#endif /* HAVE_STDINT_H */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/config_win32.h
0,0 → 1,41
/*
jbig2dec
 
Copyright (C) 2002-2003 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* configuration header file for compiling under Microsoft Windows */
 
/* update package version here */
#define PACKAGE "jbig2dec"
#define VERSION "0.3"
 
#if defined(_MSC_VER) || (defined(__BORLANDC__) && defined(__WIN32__))
/* Microsoft Visual C++ or Borland C++ */
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
/* no uint64_t */
 
# if defined(_MSC_VER)
# if _MSC_VER < 1500 /* VS 2008 has vsnprintf */
# define vsnprintf _vsnprintf
# endif
# endif
# define snprintf _snprintf
 
#endif /* _MSC_VER */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/getopt.h
0,0 → 1,180
/* Declarations for getopt.
Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
 
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
 
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
 
#ifndef _GETOPT_H
 
#ifndef __need_getopt
# define _GETOPT_H 1
#endif
 
/* If __GNU_LIBRARY__ is not already defined, either we are being used
standalone, or this is the first header included in the source file.
If we are being used with glibc, we need to include <features.h>, but
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
not defined, include <ctype.h>, which will pull in <features.h> for us
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
doesn't flood the namespace with stuff the way some other headers do.) */
#if !defined __GNU_LIBRARY__
# include <ctype.h>
#endif
 
#ifdef __cplusplus
extern "C" {
#endif
 
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
 
extern char *optarg;
 
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
 
On entry to `getopt', zero means this is the first call; initialize.
 
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
 
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
 
extern int optind;
 
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
 
extern int opterr;
 
/* Set to an option character which was unrecognized. */
 
extern int optopt;
 
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
 
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
 
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
 
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
 
struct option
{
# if (defined __STDC__ && __STDC__) || defined __cplusplus
const char *name;
# else
char *name;
# endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
 
/* Names for the values of the `has_arg' field of `struct option'. */
 
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#endif /* need getopt */
 
 
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
 
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `optopt' is set to the option letter, and '?' is
returned.
 
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `optarg'.
 
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `getopt'.
 
The argument `--' causes premature termination of argument
scanning, explicitly telling `getopt' that there are no more
options.
 
If OPTS begins with `--', then non-option arguments are treated as
arguments to the option '\0'. This behavior is specific to the GNU
`getopt'. */
 
#if (defined __STDC__ && __STDC__) || defined __cplusplus
# ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
# else /* not __GNU_LIBRARY__ */
extern int getopt ();
# endif /* __GNU_LIBRARY__ */
 
# ifndef __need_getopt
extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
const struct option *__longopts, int *__longind);
extern int getopt_long_only (int __argc, char *const *__argv,
const char *__shortopts,
const struct option *__longopts, int *__longind);
 
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int __argc, char *const *__argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only);
# endif
#else /* not __STDC__ */
extern int getopt ();
# ifndef __need_getopt
extern int getopt_long ();
extern int getopt_long_only ();
 
extern int _getopt_internal ();
# endif
#endif /* __STDC__ */
 
#ifdef __cplusplus
}
#endif
 
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
 
#endif /* getopt.h */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2.c
0,0 → 1,428
/*
jbig2dec
 
Copyright (C) 2002-2005 Artifex Software, Inc.
 
This software is provided AS-IS with no warranty,
either express or implied.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
 
#include "jbig2.h"
#include "jbig2_priv.h"
 
static void *
jbig2_default_alloc (Jbig2Allocator *allocator, size_t size)
{
return malloc (size);
}
 
static void
jbig2_default_free (Jbig2Allocator *allocator, void *p)
{
free (p);
}
 
static void *
jbig2_default_realloc (Jbig2Allocator *allocator, void *p, size_t size)
{
return realloc (p, size);
}
 
static Jbig2Allocator jbig2_default_allocator =
{
jbig2_default_alloc,
jbig2_default_free,
jbig2_default_realloc
};
 
void *
jbig2_alloc (Jbig2Allocator *allocator, size_t size)
{
return allocator->alloc (allocator, size);
}
 
void
jbig2_free (Jbig2Allocator *allocator, void *p)
{
allocator->free (allocator, p);
}
 
void *
jbig2_realloc (Jbig2Allocator *allocator, void *p, size_t size)
{
return allocator->realloc (allocator, p, size);
}
 
static int
jbig2_default_error(void *data, const char *msg,
Jbig2Severity severity, int32_t seg_idx)
{
/* report only fatal errors by default */
if (severity == JBIG2_SEVERITY_FATAL) {
fprintf(stderr, "jbig2 decoder FATAL ERROR: %s", msg);
if (seg_idx != -1) fprintf(stderr, " (segment 0x%02x)", seg_idx);
fprintf(stderr, "\n");
fflush(stderr);
}
 
return 0;
}
 
int
jbig2_error(Jbig2Ctx *ctx, Jbig2Severity severity, int32_t segment_number,
const char *fmt, ...)
{
char buf[1024];
va_list ap;
int n;
int code;
 
va_start (ap, fmt);
n = vsnprintf (buf, sizeof(buf), fmt, ap);
va_end (ap);
if (n < 0 || n == sizeof(buf))
strncpy (buf, "jbig2_error: error in generating error string", sizeof(buf));
code = ctx->error_callback (ctx->error_callback_data, buf, severity, segment_number);
if (severity == JBIG2_SEVERITY_FATAL)
code = -1;
return code;
}
 
Jbig2Ctx *
jbig2_ctx_new (Jbig2Allocator *allocator,
Jbig2Options options,
Jbig2GlobalCtx *global_ctx,
Jbig2ErrorCallback error_callback,
void *error_callback_data)
{
Jbig2Ctx *result;
 
if (allocator == NULL)
allocator = &jbig2_default_allocator;
if (error_callback == NULL)
error_callback = &jbig2_default_error;
 
result = (Jbig2Ctx *)jbig2_alloc(allocator, sizeof(Jbig2Ctx));
if (result == NULL) {
error_callback(error_callback_data, "initial context allocation failed!",
JBIG2_SEVERITY_FATAL, -1);
return result;
}
 
result->allocator = allocator;
result->options = options;
result->global_ctx = (const Jbig2Ctx *)global_ctx;
result->error_callback = error_callback;
result->error_callback_data = error_callback_data;
 
result->state = (options & JBIG2_OPTIONS_EMBEDDED) ?
JBIG2_FILE_SEQUENTIAL_HEADER :
JBIG2_FILE_HEADER;
 
result->buf = NULL;
 
result->n_segments = 0;
result->n_segments_max = 16;
result->segments = (Jbig2Segment **)jbig2_alloc(allocator, result->n_segments_max * sizeof(Jbig2Segment *));
result->segment_index = 0;
 
result->current_page = 0;
result->max_page_index = 4;
result->pages = (Jbig2Page *)jbig2_alloc(allocator, result->max_page_index * sizeof(Jbig2Page));
{
int index;
for (index = 0; index < result->max_page_index; index++) {
result->pages[index].state = JBIG2_PAGE_FREE;
result->pages[index].number = 0;
result->pages[index].image = NULL;
}
}
 
return result;
}
 
int32_t
jbig2_get_int32 (const byte *buf)
{
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
 
int16_t
jbig2_get_int16 (const byte *buf)
{
return (buf[0] << 8) | buf[1];
}
 
 
/**
* jbig2_data_in: submit data for decoding
* @ctx: The jbig2dec decoder context
* @data: a pointer to the data buffer
* @size: the size of the data buffer in bytes
*
* Copies the specified data into internal storage and attempts
* to (continue to) parse it as part of a jbig2 data stream.
*
* Return code: 0 on success
* -1 if there is a parsing error, or whatever
* the error handling callback returns
**/
int
jbig2_data_in (Jbig2Ctx *ctx, const unsigned char *data, size_t size)
{
const size_t initial_buf_size = 1024;
 
if (ctx->buf == NULL)
{
size_t buf_size = initial_buf_size;
 
do
buf_size <<= 1;
while (buf_size < size);
ctx->buf = (byte *)jbig2_alloc(ctx->allocator, buf_size);
ctx->buf_size = buf_size;
ctx->buf_rd_ix = 0;
ctx->buf_wr_ix = 0;
}
else if (ctx->buf_wr_ix + size > ctx->buf_size)
{
if (ctx->buf_rd_ix <= (ctx->buf_size >> 1) &&
ctx->buf_wr_ix - ctx->buf_rd_ix + size <= ctx->buf_size)
{
memmove(ctx->buf, ctx->buf + ctx->buf_rd_ix,
ctx->buf_wr_ix - ctx->buf_rd_ix);
}
else
{
byte *buf;
size_t buf_size = initial_buf_size;
 
do
buf_size <<= 1;
while (buf_size < ctx->buf_wr_ix - ctx->buf_rd_ix + size);
buf = (byte *)jbig2_alloc(ctx->allocator, buf_size);
memcpy(buf, ctx->buf + ctx->buf_rd_ix,
ctx->buf_wr_ix - ctx->buf_rd_ix);
jbig2_free(ctx->allocator, ctx->buf);
ctx->buf = buf;
ctx->buf_size = buf_size;
}
ctx->buf_wr_ix -= ctx->buf_rd_ix;
ctx->buf_rd_ix = 0;
}
memcpy(ctx->buf + ctx->buf_wr_ix, data, size);
ctx->buf_wr_ix += size;
 
/* data has now been added to buffer */
 
for (;;)
{
const byte jbig2_id_string[8] = { 0x97, 0x4a, 0x42, 0x32, 0x0d, 0x0a, 0x1a, 0x0a };
Jbig2Segment *segment;
size_t header_size;
int code;
 
switch (ctx->state)
{
case JBIG2_FILE_HEADER:
/* D.4.1 */
if (ctx->buf_wr_ix - ctx->buf_rd_ix < 9)
return 0;
if (memcmp(ctx->buf + ctx->buf_rd_ix, jbig2_id_string, 8))
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"Not a JBIG2 file header");
/* D.4.2 */
ctx->file_header_flags = ctx->buf[ctx->buf_rd_ix + 8];
if (ctx->file_header_flags & 0xFC) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
"reserved bits (2-7) of file header flags are not zero (0x%02x)", ctx->file_header_flags);
}
/* D.4.3 */
if (!(ctx->file_header_flags & 2)) /* number of pages is known */
{
if (ctx->buf_wr_ix - ctx->buf_rd_ix < 13)
return 0;
ctx->n_pages = jbig2_get_int32(ctx->buf + ctx->buf_rd_ix + 9);
ctx->buf_rd_ix += 13;
if (ctx->n_pages == 1)
jbig2_error(ctx, JBIG2_SEVERITY_INFO, -1, "file header indicates a single page document");
else
jbig2_error(ctx, JBIG2_SEVERITY_INFO, -1, "file header indicates a %d page document", ctx->n_pages);
}
else /* number of pages not known */
{
ctx->n_pages=0;
ctx->buf_rd_ix += 9;
}
/* determine the file organization based on the flags - D.4.2 again */
if (ctx->file_header_flags & 1)
{
ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "file header indicates sequential organization");
}
else
{
ctx->state = JBIG2_FILE_RANDOM_HEADERS;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "file header indicates random-access organization");
 
}
break;
case JBIG2_FILE_SEQUENTIAL_HEADER:
case JBIG2_FILE_RANDOM_HEADERS:
segment = jbig2_parse_segment_header(ctx, ctx->buf + ctx->buf_rd_ix,
ctx->buf_wr_ix - ctx->buf_rd_ix,
&header_size);
if (segment == NULL)
return 0; /* need more data */
ctx->buf_rd_ix += header_size;
 
if (ctx->n_segments == ctx->n_segments_max)
ctx->segments = (Jbig2Segment **)jbig2_realloc(ctx->allocator,
ctx->segments, (ctx->n_segments_max <<= 2) * sizeof(Jbig2Segment *));
 
ctx->segments[ctx->n_segments++] = segment;
if (ctx->state == JBIG2_FILE_RANDOM_HEADERS)
{
if ((segment->flags & 63) == 51) /* end of file */
ctx->state = JBIG2_FILE_RANDOM_BODIES;
}
else /* JBIG2_FILE_SEQUENTIAL_HEADER */
ctx->state = JBIG2_FILE_SEQUENTIAL_BODY;
break;
case JBIG2_FILE_SEQUENTIAL_BODY:
case JBIG2_FILE_RANDOM_BODIES:
segment = ctx->segments[ctx->segment_index];
if (segment->data_length > ctx->buf_wr_ix - ctx->buf_rd_ix)
return 0; /* need more data */
code = jbig2_parse_segment(ctx, segment, ctx->buf + ctx->buf_rd_ix);
ctx->buf_rd_ix += segment->data_length;
ctx->segment_index++;
if (ctx->state == JBIG2_FILE_RANDOM_BODIES)
{
if (ctx->segment_index == ctx->n_segments)
ctx->state = JBIG2_FILE_EOF;
}
else /* JBIG2_FILE_SEQUENCIAL_BODY */
{
ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
}
if (code < 0)
{
ctx->state = JBIG2_FILE_EOF;
return code;
}
break;
case JBIG2_FILE_EOF:
if (ctx->buf_rd_ix == ctx->buf_wr_ix)
return 0;
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
"Garbage beyond end of file");
}
}
return 0;
}
 
void
jbig2_ctx_free (Jbig2Ctx *ctx)
{
Jbig2Allocator *ca = ctx->allocator;
int i;
 
jbig2_free(ca, ctx->buf);
if (ctx->segments != NULL) {
for (i = 0; i < ctx->n_segments; i++)
jbig2_free_segment(ctx, ctx->segments[i]);
jbig2_free(ca, ctx->segments);
}
 
if (ctx->pages != NULL) {
for (i = 0; i <= ctx->current_page; i++)
if (ctx->pages[i].image != NULL)
jbig2_image_release(ctx, ctx->pages[i].image);
jbig2_free(ca, ctx->pages);
}
 
jbig2_free(ca, ctx);
}
 
Jbig2GlobalCtx *jbig2_make_global_ctx (Jbig2Ctx *ctx)
{
return (Jbig2GlobalCtx *)ctx;
}
 
void jbig2_global_ctx_free(Jbig2GlobalCtx *global_ctx)
{
jbig2_ctx_free((Jbig2Ctx *)global_ctx);
}
 
 
/* I'm not committed to keeping the word stream interface. It's handy
when you think you may be streaming your input, but if you're not
(as is currently the case), it just adds complexity.
*/
 
typedef struct {
Jbig2WordStream super;
const byte *data;
size_t size;
} Jbig2WordStreamBuf;
 
static uint32_t
jbig2_word_stream_buf_get_next_word(Jbig2WordStream *self, int offset)
{
Jbig2WordStreamBuf *z = (Jbig2WordStreamBuf *)self;
const byte *data = z->data;
uint32_t result;
 
if (offset + 4 < z->size)
result = (data[offset] << 24) | (data[offset + 1] << 16) |
(data[offset + 2] << 8) | data[offset + 3];
else if (offset >= z->size)
return 0;
else
{
int i;
 
result = 0;
for (i = 0; i < z->size - offset; i++)
result |= data[offset + i] << ((3 - i) << 3);
}
return result;
}
 
Jbig2WordStream *
jbig2_word_stream_buf_new(Jbig2Ctx *ctx, const byte *data, size_t size)
{
Jbig2WordStreamBuf *result = (Jbig2WordStreamBuf *)jbig2_alloc(ctx->allocator, sizeof(Jbig2WordStreamBuf));
 
result->super.get_next_word = jbig2_word_stream_buf_get_next_word;
result->data = data;
result->size = size;
 
return &result->super;
}
 
void
jbig2_word_stream_buf_free(Jbig2Ctx *ctx, Jbig2WordStream *ws)
{
jbig2_free(ctx->allocator, ws);
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2.h
0,0 → 1,135
/*
jbig2dec
 
Copyright (C) 2002-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef __cplusplus
extern "C" {
#endif
 
#ifndef _JBIG2_H
#define _JBIG2_H
 
/* warning levels */
typedef enum {
JBIG2_SEVERITY_DEBUG,
JBIG2_SEVERITY_INFO,
JBIG2_SEVERITY_WARNING,
JBIG2_SEVERITY_FATAL
} Jbig2Severity;
 
typedef enum {
JBIG2_OPTIONS_EMBEDDED = 1
} Jbig2Options;
 
/* forward public structure declarations */
typedef struct _Jbig2Allocator Jbig2Allocator;
typedef struct _Jbig2Ctx Jbig2Ctx;
typedef struct _Jbig2GlobalCtx Jbig2GlobalCtx;
typedef struct _Jbig2Segment Jbig2Segment;
typedef struct _Jbig2Image Jbig2Image;
 
/* private structures */
typedef struct _Jbig2Page Jbig2Page;
typedef struct _Jbig2SymbolDictionary Jbig2SymbolDictionary;
 
/*
this is the general image structure used by the jbig2dec library
images are 1 bpp, packed into rows a byte at a time. stride gives
the byte offset to the next row, while width and height define
the size of the image area in pixels.
*/
 
struct _Jbig2Image {
int width, height, stride;
uint8_t *data;
int refcount;
};
 
Jbig2Image* jbig2_image_new(Jbig2Ctx *ctx, int width, int height);
Jbig2Image* jbig2_image_clone(Jbig2Ctx *ctx, Jbig2Image *image);
void jbig2_image_release(Jbig2Ctx *ctx, Jbig2Image *image);
void jbig2_image_free(Jbig2Ctx *ctx, Jbig2Image *image);
void jbig2_image_clear(Jbig2Ctx *ctx, Jbig2Image *image, int value);
Jbig2Image *jbig2_image_resize(Jbig2Ctx *ctx, Jbig2Image *image,
int width, int height);
 
/* errors are returned from the library via a callback. If no callback
is provided (a NULL argument is passed ot jbig2_ctx_new) a default
handler is used which prints fatal errors to the stderr stream. */
 
/* error callback */
typedef int (*Jbig2ErrorCallback) (void *data,
const char *msg, Jbig2Severity severity,
int32_t seg_idx);
 
/* memory allocation is likewise done via a set of callbacks so that
clients can better control memory usage. If a NULL is passed for
this argumennt of jbig2_ctx_new, a default allocator based on malloc()
is used. */
 
/* dynamic memory callbacks */
struct _Jbig2Allocator {
void *(*alloc) (Jbig2Allocator *allocator, size_t size);
void (*free) (Jbig2Allocator *allocator, void *p);
void *(*realloc) (Jbig2Allocator *allocator, void *p, size_t size);
};
 
/* decoder context */
Jbig2Ctx *jbig2_ctx_new (Jbig2Allocator *allocator,
Jbig2Options options,
Jbig2GlobalCtx *global_ctx,
Jbig2ErrorCallback error_callback,
void *error_callback_data);
void jbig2_ctx_free (Jbig2Ctx *ctx);
 
/* global context for embedded streams */
Jbig2GlobalCtx *jbig2_make_global_ctx (Jbig2Ctx *ctx);
void jbig2_global_ctx_free (Jbig2GlobalCtx *global_ctx);
 
/* submit data to the decoder */
int jbig2_data_in (Jbig2Ctx *ctx, const unsigned char *data, size_t size);
 
/* get the next available decoded page image. NULL means there isn't one. */
Jbig2Image *jbig2_page_out (Jbig2Ctx *ctx);
/* mark a returned page image as no longer needed. */
int jbig2_release_page (Jbig2Ctx *ctx, Jbig2Image *image);
/* mark the current page as complete, simulating an end-of-page segment (for broken streams) */
int jbig2_complete_page (Jbig2Ctx *ctx);
 
 
/* segment header routines */
 
struct _Jbig2Segment {
uint32_t number;
uint8_t flags;
uint32_t page_association;
size_t data_length;
int referred_to_segment_count;
uint32_t *referred_to_segments;
void *result;
};
 
Jbig2Segment *jbig2_parse_segment_header (Jbig2Ctx *ctx, uint8_t *buf, size_t buf_size,
size_t *p_header_size);
int jbig2_parse_segment (Jbig2Ctx *ctx, Jbig2Segment *segment,
const uint8_t *segment_data);
void jbig2_free_segment (Jbig2Ctx *ctx, Jbig2Segment *segment);
 
Jbig2Segment *jbig2_find_segment(Jbig2Ctx *ctx, uint32_t number);
 
#endif /* _JBIG2_H */
 
#ifdef __cplusplus
}
#endif
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_arith.c
0,0 → 1,394
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is provided AS-IS with no warranty,
either express or implied.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stdio.h>
#include <stdlib.h>
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
 
#ifdef JBIG2_DEBUG
#include <stdio.h>
#endif
 
struct _Jbig2ArithState {
uint32_t C;
int A;
 
int CT;
 
uint32_t next_word;
int next_word_bytes;
 
Jbig2WordStream *ws;
int offset;
};
 
#undef SOFTWARE_CONVENTION
 
/*
A note on the "software conventions".
 
Previously, I had misinterpreted the spec, and had thought that the
spec's description of the "software convention" was wrong. Now I
believe that this code is both correct and matches the spec, with
SOFTWARE_CONVENTION defined or not. Thanks to William Rucklidge for
the clarification.
 
In any case, my benchmarking indicates no speed difference at all.
Therefore, for now we will just use the normative version.
 
*/
 
static void
jbig2_arith_bytein (Jbig2ArithState *as)
{
byte B;
 
/* invariant: as->next_word_bytes > 0 */
 
/* Figure G.3 */
B = (byte)((as->next_word >> 24) & 0xFF);
if (B == 0xFF)
{
byte B1;
if (as->next_word_bytes == 1)
{
Jbig2WordStream *ws = as->ws;
as->next_word = ws->get_next_word (ws, as->offset);
as->offset += 4;
B1 = (byte)((as->next_word >> 24) & 0xFF);
if (B1 > 0x8F)
{
#ifdef JBIG2_DEBUG_ARITH
fprintf(stderr, "read %02x (aa)\n", B);
#endif
#ifndef SOFTWARE_CONVENTION
as->C += 0xFF00;
#endif
as->CT = 8;
as->next_word = (0xFF00 | B1) << 16;
as->next_word_bytes = 2;
}
else
{
#ifdef JBIG2_DEBUG_ARITH
fprintf(stderr, "read %02x (a)\n", B);
#endif
#ifdef SOFTWARE_CONVENTION
as->C += 0xFE00 - (B1 << 9);
#else
as->C += B1 << 9;
#endif
as->CT = 7;
as->next_word_bytes = 4;
}
}
else
{
B1 = (byte)((as->next_word >> 16) & 0xFF);
if (B1 > 0x8F)
{
#ifdef JBIG2_DEBUG_ARITH
fprintf(stderr, "read %02x (ba)\n", B);
#endif
#ifndef SOFTWARE_CONVENTION
as->C += 0xFF00;
#endif
as->CT = 8;
}
else
{
as->next_word_bytes--;
as->next_word <<= 8;
#ifdef JBIG2_DEBUG_ARITH
fprintf(stderr, "read %02x (b)\n", B);
#endif
 
#ifdef SOFTWARE_CONVENTION
as->C += 0xFE00 - (B1 << 9);
#else
as->C += (B1 << 9);
#endif
as->CT = 7;
}
}
}
else
{
#ifdef JBIG2_DEBUG_ARITH
fprintf(stderr, "read %02x\n", B);
#endif
as->CT = 8;
as->next_word <<= 8;
as->next_word_bytes--;
if (as->next_word_bytes == 0)
{
Jbig2WordStream *ws = as->ws;
 
as->next_word = ws->get_next_word (ws, as->offset);
as->offset += 4;
as->next_word_bytes = 4;
}
B = (byte)((as->next_word >> 24) & 0xFF);
#ifdef SOFTWARE_CONVENTION
as->C += 0xFF00 - (B << 8);
#else
as->C += (B << 8);
#endif
}
}
 
#if defined(JBIG2_DEBUG) || defined(JBIG2_DEBUG_ARITH)
#include <stdio.h>
 
static void
jbig2_arith_trace (Jbig2ArithState *as, Jbig2ArithCx cx)
{
fprintf(stderr, "I = %2d, MPS = %d, A = %04x, CT = %2d, C = %08x\n",
cx & 0x7f, cx >> 7, as->A, as->CT, as->C);
}
#endif
 
/** Allocate and initialize a new arithmetic coding state
* the returned pointer can simply be freed; this does
* not affect the associated Jbig2WordStream.
*/
Jbig2ArithState *
jbig2_arith_new (Jbig2Ctx *ctx, Jbig2WordStream *ws)
{
Jbig2ArithState *result;
 
result = (Jbig2ArithState *)jbig2_alloc(ctx->allocator,
sizeof(Jbig2ArithState));
 
result->ws = ws;
 
result->next_word = ws->get_next_word (ws, 0);
result->next_word_bytes = 4;
result->offset = 4;
 
/* Figure G.1 */
#ifdef SOFTWARE_CONVENTION
result->C = (~(result->next_word >> 8)) & 0xFF0000;
#else
result->C = (result->next_word >> 8) & 0xFF0000;
#endif
 
jbig2_arith_bytein (result);
result->C <<= 7;
result->CT -= 7;
result->A = 0x8000;
 
return result;
}
 
/* could put bit fields in to minimize memory usage */
typedef struct {
unsigned short Qe;
byte mps_xor; /* mps_xor = index ^ NMPS */
byte lps_xor; /* lps_xor = index ^ NLPS ^ (SWITCH << 7) */
} Jbig2ArithQe;
 
const Jbig2ArithQe jbig2_arith_Qe[] = {
{ 0x5601, 1 ^ 0, 1 ^ 0 ^ 0x80 },
{ 0x3401, 2 ^ 1, 6 ^ 1 },
{ 0x1801, 3 ^ 2, 9 ^ 2 },
{ 0x0AC1, 4 ^ 3, 12 ^ 3 },
{ 0x0521, 5 ^ 4, 29 ^ 4 },
{ 0x0221, 38 ^ 5, 33 ^ 5 },
{ 0x5601, 7 ^ 6, 6 ^ 6 ^ 0x80 },
{ 0x5401, 8 ^ 7, 14 ^ 7 },
{ 0x4801, 9 ^ 8, 14 ^ 8 },
{ 0x3801, 10 ^ 9, 14 ^ 9 },
{ 0x3001, 11 ^ 10, 17 ^ 10 },
{ 0x2401, 12 ^ 11, 18 ^ 11 },
{ 0x1C01, 13 ^ 12, 20 ^ 12 },
{ 0x1601, 29 ^ 13, 21 ^ 13 },
{ 0x5601, 15 ^ 14, 14 ^ 14 ^ 0x80 },
{ 0x5401, 16 ^ 15, 14 ^ 15 },
{ 0x5101, 17 ^ 16, 15 ^ 16 },
{ 0x4801, 18 ^ 17, 16 ^ 17 },
{ 0x3801, 19 ^ 18, 17 ^ 18 },
{ 0x3401, 20 ^ 19, 18 ^ 19 },
{ 0x3001, 21 ^ 20, 19 ^ 20 },
{ 0x2801, 22 ^ 21, 19 ^ 21 },
{ 0x2401, 23 ^ 22, 20 ^ 22 },
{ 0x2201, 24 ^ 23, 21 ^ 23 },
{ 0x1C01, 25 ^ 24, 22 ^ 24 },
{ 0x1801, 26 ^ 25, 23 ^ 25 },
{ 0x1601, 27 ^ 26, 24 ^ 26 },
{ 0x1401, 28 ^ 27, 25 ^ 27 },
{ 0x1201, 29 ^ 28, 26 ^ 28 },
{ 0x1101, 30 ^ 29, 27 ^ 29 },
{ 0x0AC1, 31 ^ 30, 28 ^ 30 },
{ 0x09C1, 32 ^ 31, 29 ^ 31 },
{ 0x08A1, 33 ^ 32, 30 ^ 32 },
{ 0x0521, 34 ^ 33, 31 ^ 33 },
{ 0x0441, 35 ^ 34, 32 ^ 34 },
{ 0x02A1, 36 ^ 35, 33 ^ 35 },
{ 0x0221, 37 ^ 36, 34 ^ 36 },
{ 0x0141, 38 ^ 37, 35 ^ 37 },
{ 0x0111, 39 ^ 38, 36 ^ 38 },
{ 0x0085, 40 ^ 39, 37 ^ 39 },
{ 0x0049, 41 ^ 40, 38 ^ 40 },
{ 0x0025, 42 ^ 41, 39 ^ 41 },
{ 0x0015, 43 ^ 42, 40 ^ 42 },
{ 0x0009, 44 ^ 43, 41 ^ 43 },
{ 0x0005, 45 ^ 44, 42 ^ 44 },
{ 0x0001, 45 ^ 45, 43 ^ 45 },
{ 0x5601, 46 ^ 46, 46 ^ 46 }
};
 
static void
jbig2_arith_renormd (Jbig2ArithState *as)
{
/* Figure E.18 */
do
{
if (as->CT == 0)
jbig2_arith_bytein (as);
as->A <<= 1;
as->C <<= 1;
as->CT--;
}
while ((as->A & 0x8000) == 0);
}
 
bool
jbig2_arith_decode (Jbig2ArithState *as, Jbig2ArithCx *pcx)
{
Jbig2ArithCx cx = *pcx;
const Jbig2ArithQe *pqe = &jbig2_arith_Qe[cx & 0x7f];
bool D;
 
/* Figure G.2 */
as->A -= pqe->Qe;
if (
#ifdef SOFTWARE_CONVENTION
/* Note: I do not think this is correct. See above. */
(as->C >> 16) < as->A
#else
!((as->C >> 16) < pqe->Qe)
#endif
)
{
#ifndef SOFTWARE_CONVENTION
as->C -= pqe->Qe << 16;
#endif
if ((as->A & 0x8000) == 0)
{
/* MPS_EXCHANGE, Figure E.16 */
if (as->A < pqe->Qe)
{
D = 1 - (cx >> 7);
*pcx ^= pqe->lps_xor;
}
else
{
D = cx >> 7;
*pcx ^= pqe->mps_xor;
}
jbig2_arith_renormd (as);
return D;
}
else
return cx >> 7;
}
else
{
#ifdef SOFTWARE_CONVENTION
as->C -= (as->A) << 16;
#endif
/* LPS_EXCHANGE, Figure E.17 */
if (as->A < pqe->Qe)
{
as->A = pqe->Qe;
D = cx >> 7;
*pcx ^= pqe->mps_xor;
}
else
{
as->A = pqe->Qe;
D = 1 - (cx >> 7);
*pcx ^= pqe->lps_xor;
}
jbig2_arith_renormd (as);
return D;
}
}
 
#ifdef TEST
 
static uint32_t
test_get_word (Jbig2WordStream *self, int offset)
{
byte stream[] = {
0x84, 0xC7, 0x3B, 0xFC, 0xE1, 0xA1, 0x43, 0x04, 0x02, 0x20, 0x00, 0x00,
0x41, 0x0D, 0xBB, 0x86, 0xF4, 0x31, 0x7F, 0xFF, 0x88, 0xFF, 0x37, 0x47,
0x1A, 0xDB, 0x6A, 0xDF, 0xFF, 0xAC,
0x00, 0x00
};
if (offset >= sizeof(stream))
return 0;
else
return (stream[offset] << 24) | (stream[offset + 1] << 16) |
(stream[offset + 2] << 8) | stream[offset + 3];
}
 
int
main (int argc, char **argv)
{
Jbig2Ctx *ctx;
Jbig2WordStream ws;
Jbig2ArithState *as;
int i;
Jbig2ArithCx cx = 0;
 
ctx = jbig2_ctx_new(NULL, 0, NULL, NULL, NULL);
 
ws.get_next_word = test_get_word;
as = jbig2_arith_new (ctx, &ws);
#ifdef JBIG2_DEBUG_ARITH
jbig2_arith_trace (as, cx);
#endif
 
for (i = 0; i < 256; i++)
{
bool D;
 
D = jbig2_arith_decode (as, &cx);
#ifdef JBIG2_DEBUG_ARITH
fprintf(stderr, "%3d: D = %d, ", i, D);
jbig2_arith_trace (as, cx);
#endif
}
 
jbig2_free(ctx->allocator, as);
 
jbig2_ctx_free(ctx);
 
return 0;
}
#endif
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_arith.h
0,0 → 1,31
/*
jbig2dec
 
Copyright (C) 2001 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
typedef struct _Jbig2ArithState Jbig2ArithState;
 
/* An arithmetic coding context is stored as a single byte, with the
index in the low order 7 bits (actually only 6 are used), and the
MPS in the top bit. */
typedef unsigned char Jbig2ArithCx;
 
/* allocate and initialize a new arithmetic coding state */
Jbig2ArithState *
jbig2_arith_new (Jbig2Ctx *ctx, Jbig2WordStream *ws);
 
/* decode a bit */
bool
jbig2_arith_decode (Jbig2ArithState *as, Jbig2ArithCx *pcx);
 
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_arith_iaid.c
0,0 → 1,91
/*
jbig2dec
 
Copyright (C) 2001 Artifex Software, Inc.
 
This software is provided AS-IS with no warranty,
either express or implied.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* Annex A.3 */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h>
#include <string.h> /* memset() */
 
#ifdef VERBOSE
#include <stdio.h> /* for debug printing only */
#endif
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_arith_iaid.h"
 
struct _Jbig2ArithIaidCtx {
int SBSYMCODELEN;
Jbig2ArithCx *IAIDx;
};
 
Jbig2ArithIaidCtx *
jbig2_arith_iaid_ctx_new(Jbig2Ctx *ctx, int SBSYMCODELEN)
{
Jbig2ArithIaidCtx *result = jbig2_new(ctx, Jbig2ArithIaidCtx, 1);
int ctx_size = 1 << SBSYMCODELEN;
 
result->SBSYMCODELEN = SBSYMCODELEN;
result->IAIDx = jbig2_alloc(ctx->allocator, ctx_size);
memset(result->IAIDx, 0, ctx_size);
 
return result;
}
 
/* A.3 */
/* Return value: -1 on error, 0 on normal value */
int
jbig2_arith_iaid_decode(Jbig2ArithIaidCtx *ctx, Jbig2ArithState *as,
int32_t *p_result)
{
Jbig2ArithCx *IAIDx = ctx->IAIDx;
int SBSYMCODELEN = ctx->SBSYMCODELEN;
int PREV = 1;
int D;
int i;
 
/* A.3 (2) */
for (i = 0; i < SBSYMCODELEN; i++)
{
D = jbig2_arith_decode(as, &IAIDx[PREV]);
#ifdef VERBOSE
fprintf(stderr, "IAID%x: D = %d\n", PREV, D);
#endif
PREV = (PREV << 1) | D;
}
/* A.3 (3) */
PREV -= 1 << SBSYMCODELEN;
#ifdef VERBOSE
fprintf(stderr, "IAID result: %d\n", PREV);
#endif
*p_result = PREV;
return 0;
}
 
void
jbig2_arith_iaid_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIaidCtx *iax)
{
jbig2_free(ctx->allocator, iax->IAIDx);
jbig2_free(ctx->allocator, iax);
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_arith_iaid.h
0,0 → 1,26
/*
jbig2dec
 
Copyright (C) 2001 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
typedef struct _Jbig2ArithIaidCtx Jbig2ArithIaidCtx;
 
Jbig2ArithIaidCtx *
jbig2_arith_iaid_ctx_new(Jbig2Ctx *ctx, int SBSYMCODELEN);
 
int
jbig2_arith_iaid_decode(Jbig2ArithIaidCtx *ctx, Jbig2ArithState *as,
int32_t *p_result);
 
void
jbig2_arith_iaid_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIaidCtx *iax);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_arith_int.c
0,0 → 1,139
/*
jbig2dec
 
Copyright (C) 2001 Artifex Software, Inc.
 
This software is provided AS-IS with no warranty,
either express or implied.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* Annex A */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h>
#include <string.h> /* memset() */
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_arith_int.h"
 
struct _Jbig2ArithIntCtx {
Jbig2ArithCx IAx[512];
};
 
Jbig2ArithIntCtx *
jbig2_arith_int_ctx_new(Jbig2Ctx *ctx)
{
Jbig2ArithIntCtx *result = jbig2_new(ctx, Jbig2ArithIntCtx, 1);
 
memset(result->IAx, 0, sizeof(result->IAx));
 
return result;
}
 
/* A.2 */
/* Return value: -1 on error, 0 on normal value, 1 on OOB return. */
int
jbig2_arith_int_decode(Jbig2ArithIntCtx *ctx, Jbig2ArithState *as,
int32_t *p_result)
{
Jbig2ArithCx *IAx = ctx->IAx;
int PREV = 1;
int S, V;
int bit;
int n_tail, offset;
int i;
 
S = jbig2_arith_decode(as, &IAx[PREV]);
PREV = (PREV << 1) | S;
 
bit = jbig2_arith_decode(as, &IAx[PREV]);
PREV = (PREV << 1) | bit;
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
PREV = (PREV << 1) | bit;
 
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
PREV = (PREV << 1) | bit;
 
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
PREV = (PREV << 1) | bit;
 
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
PREV = (PREV << 1) | bit;
 
if (bit)
{
n_tail = 32;
offset = 4436;
}
else
{
n_tail = 12;
offset = 340;
}
}
else
{
n_tail = 8;
offset = 84;
}
}
else
{
n_tail = 6;
offset = 20;
}
}
else
{
n_tail = 4;
offset = 4;
}
}
else
{
n_tail = 2;
offset = 0;
}
 
V = 0;
for (i = 0; i < n_tail; i++)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
PREV = ((PREV << 1) & 511) | (PREV & 256) | bit;
V = (V << 1) | bit;
}
 
V += offset;
V = S ? -V : V;
*p_result = V;
return S && V == 0 ? 1 : 0;
}
 
void
jbig2_arith_int_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIntCtx *iax)
{
jbig2_free(ctx->allocator, iax);
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_arith_int.h
0,0 → 1,26
/*
jbig2dec
 
Copyright (C) 2001 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
typedef struct _Jbig2ArithIntCtx Jbig2ArithIntCtx;
 
Jbig2ArithIntCtx *
jbig2_arith_int_ctx_new(Jbig2Ctx *ctx);
 
int
jbig2_arith_int_decode(Jbig2ArithIntCtx *ctx, Jbig2ArithState *as,
int32_t *p_result);
 
void
jbig2_arith_int_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIntCtx *iax);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_generic.c
0,0 → 1,854
/*
jbig2dec
 
Copyright (C) 2002-2005 Artifex Software, Inc.
 
This software is provided AS-IS with no warranty,
either express or implied.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/**
* Generic region handlers.
**/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h>
#include <string.h> /* memcpy(), memset() */
 
#ifdef OUTPUT_PBM
#include <stdio.h>
#endif
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_image.h"
#include "jbig2_arith.h"
#include "jbig2_generic.h"
#include "jbig2_mmr.h"
 
/* return the appropriate context size for the given template */
int
jbig2_generic_stats_size(Jbig2Ctx *ctx, int template)
{
int stats_size = template == 0 ? 1 << 16 :
template == 1 ? 1 << 1 << 13 : 1 << 10;
return stats_size;
}
 
 
static int
jbig2_decode_generic_template0(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
const int rowstride = image->stride;
int x, y;
byte *gbreg_line = (byte *)image->data;
 
/* todo: currently we only handle the nominal gbat location */
 
#ifdef OUTPUT_PBM
printf("P4\n%d %d\n", GBW, GBH);
#endif
 
for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
uint32_t line_m2;
int padded_width = (GBW + 7) & -8;
 
line_m1 = (y >= 1) ? gbreg_line[-rowstride] : 0;
line_m2 = (y >= 2) ? gbreg_line[-(rowstride << 1)] << 6 : 0;
CONTEXT = (line_m1 & 0x7f0) | (line_m2 & 0xf800);
 
/* 6.2.5.7 3d */
for (x = 0; x < padded_width; x += 8)
{
byte result = 0;
int x_minor;
int minor_width = GBW - x > 8 ? 8 : GBW - x;
 
if (y >= 1)
line_m1 = (line_m1 << 8) |
(x + 8 < GBW ? gbreg_line[-rowstride + (x >> 3) + 1] : 0);
 
if (y >= 2)
line_m2 = (line_m2 << 8) |
(x + 8 < GBW ? gbreg_line[-(rowstride << 1) + (x >> 3) + 1] << 6: 0);
 
/* This is the speed-critical inner loop. */
for (x_minor = 0; x_minor < minor_width; x_minor++)
{
bool bit;
 
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x7bf7) << 1) | bit |
((line_m1 >> (7 - x_minor)) & 0x10) |
((line_m2 >> (7 - x_minor)) & 0x800);
}
gbreg_line[x >> 3] = result;
}
#ifdef OUTPUT_PBM
fwrite(gbreg_line, 1, rowstride, stdout);
#endif
gbreg_line += rowstride;
}
 
return 0;
}
 
static int
jbig2_decode_generic_template0_unopt(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
uint32_t CONTEXT;
int x,y;
bool bit;
 
/* this version is generic and easy to understand, but very slow */
 
for (y = 0; y < GBH; y++) {
for (x = 0; x < GBW; x++) {
CONTEXT = 0;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y) << 0;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0],
y + params->gbat[1]) << 4;
CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 5;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 6;
CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 7;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 9;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[2],
y + params->gbat[3]) << 10;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[4],
y + params->gbat[5]) << 11;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 12;
CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 2) << 13;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6],
y + params->gbat[7]) << 15;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
}
return 0;
}
 
static int
jbig2_decode_generic_template1(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
const int rowstride = image->stride;
int x, y;
byte *gbreg_line = (byte *)image->data;
 
/* todo: currently we only handle the nominal gbat location */
 
#ifdef OUTPUT_PBM
printf("P4\n%d %d\n", GBW, GBH);
#endif
 
for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
uint32_t line_m2;
int padded_width = (GBW + 7) & -8;
 
line_m1 = (y >= 1) ? gbreg_line[-rowstride] : 0;
line_m2 = (y >= 2) ? gbreg_line[-(rowstride << 1)] << 5 : 0;
CONTEXT = ((line_m1 >> 1) & 0x1f8) | ((line_m2 >> 1) & 0x1e00);
 
/* 6.2.5.7 3d */
for (x = 0; x < padded_width; x += 8)
{
byte result = 0;
int x_minor;
int minor_width = GBW - x > 8 ? 8 : GBW - x;
 
if (y >= 1)
line_m1 = (line_m1 << 8) |
(x + 8 < GBW ? gbreg_line[-rowstride + (x >> 3) + 1] : 0);
 
if (y >= 2)
line_m2 = (line_m2 << 8) |
(x + 8 < GBW ? gbreg_line[-(rowstride << 1) + (x >> 3) + 1] << 5: 0);
 
/* This is the speed-critical inner loop. */
for (x_minor = 0; x_minor < minor_width; x_minor++)
{
bool bit;
 
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0xefb) << 1) | bit |
((line_m1 >> (8 - x_minor)) & 0x8) |
((line_m2 >> (8 - x_minor)) & 0x200);
}
gbreg_line[x >> 3] = result;
}
#ifdef OUTPUT_PBM
fwrite(gbreg_line, 1, rowstride, stdout);
#endif
gbreg_line += rowstride;
}
 
return 0;
}
 
static int
jbig2_decode_generic_template2(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
const int rowstride = image->stride;
int x, y;
byte *gbreg_line = (byte *)image->data;
 
/* todo: currently we only handle the nominal gbat location */
 
#ifdef OUTPUT_PBM
printf("P4\n%d %d\n", GBW, GBH);
#endif
 
for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
uint32_t line_m2;
int padded_width = (GBW + 7) & -8;
 
line_m1 = (y >= 1) ? gbreg_line[-rowstride] : 0;
line_m2 = (y >= 2) ? gbreg_line[-(rowstride << 1)] << 4 : 0;
CONTEXT = ((line_m1 >> 3) & 0x7c) | ((line_m2 >> 3) & 0x380);
 
/* 6.2.5.7 3d */
for (x = 0; x < padded_width; x += 8)
{
byte result = 0;
int x_minor;
int minor_width = GBW - x > 8 ? 8 : GBW - x;
 
if (y >= 1)
line_m1 = (line_m1 << 8) |
(x + 8 < GBW ? gbreg_line[-rowstride + (x >> 3) + 1] : 0);
 
if (y >= 2)
line_m2 = (line_m2 << 8) |
(x + 8 < GBW ? gbreg_line[-(rowstride << 1) + (x >> 3) + 1] << 4: 0);
 
/* This is the speed-critical inner loop. */
for (x_minor = 0; x_minor < minor_width; x_minor++)
{
bool bit;
 
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x1bd) << 1) | bit |
((line_m1 >> (10 - x_minor)) & 0x4) |
((line_m2 >> (10 - x_minor)) & 0x80);
}
gbreg_line[x >> 3] = result;
}
#ifdef OUTPUT_PBM
fwrite(gbreg_line, 1, rowstride, stdout);
#endif
gbreg_line += rowstride;
}
 
return 0;
}
 
static int
jbig2_decode_generic_template2a(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
const int rowstride = image->stride;
int x, y;
byte *gbreg_line = (byte *)image->data;
 
/* This is a special case for GBATX1 = 3, GBATY1 = -1 */
 
#ifdef OUTPUT_PBM
printf("P4\n%d %d\n", GBW, GBH);
#endif
 
for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
uint32_t line_m2;
int padded_width = (GBW + 7) & -8;
 
line_m1 = (y >= 1) ? gbreg_line[-rowstride] : 0;
line_m2 = (y >= 2) ? gbreg_line[-(rowstride << 1)] << 4 : 0;
CONTEXT = ((line_m1 >> 3) & 0x78) | ((line_m1 >> 2) & 0x4) | ((line_m2 >> 3) & 0x380);
 
/* 6.2.5.7 3d */
for (x = 0; x < padded_width; x += 8)
{
byte result = 0;
int x_minor;
int minor_width = GBW - x > 8 ? 8 : GBW - x;
 
if (y >= 1)
line_m1 = (line_m1 << 8) |
(x + 8 < GBW ? gbreg_line[-rowstride + (x >> 3) + 1] : 0);
 
if (y >= 2)
line_m2 = (line_m2 << 8) |
(x + 8 < GBW ? gbreg_line[-(rowstride << 1) + (x >> 3) + 1] << 4: 0);
 
/* This is the speed-critical inner loop. */
for (x_minor = 0; x_minor < minor_width; x_minor++)
{
bool bit;
 
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x1b9) << 1) | bit |
((line_m1 >> (10 - x_minor)) & 0x8) |
((line_m1 >> (9 - x_minor)) & 0x4) |
((line_m2 >> (10 - x_minor)) & 0x80);
}
gbreg_line[x >> 3] = result;
}
#ifdef OUTPUT_PBM
fwrite(gbreg_line, 1, rowstride, stdout);
#endif
gbreg_line += rowstride;
}
 
return 0;
}
 
static int
jbig2_decode_generic_template3(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
const int rowstride = image->stride;
byte *gbreg_line = (byte *)image->data;
int x, y;
 
/* this routine only handles the nominal AT location */
 
#ifdef OUTPUT_PBM
printf("P4\n%d %d\n", GBW, GBH);
#endif
 
for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
int padded_width = (GBW + 7) & -8;
 
line_m1 = (y >= 1) ? gbreg_line[-rowstride] : 0;
CONTEXT = (line_m1 >> 1) & 0x3f0;
 
/* 6.2.5.7 3d */
for (x = 0; x < padded_width; x += 8)
{
byte result = 0;
int x_minor;
int minor_width = GBW - x > 8 ? 8 : GBW - x;
 
if (y >= 1)
line_m1 = (line_m1 << 8) |
(x + 8 < GBW ? gbreg_line[-rowstride + (x >> 3) + 1] : 0);
 
/* This is the speed-critical inner loop. */
for (x_minor = 0; x_minor < minor_width; x_minor++)
{
bool bit;
 
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x1f7) << 1) | bit |
((line_m1 >> (10 - x_minor)) & 0x010);
}
gbreg_line[x >> 3] = result;
}
#ifdef OUTPUT_PBM
fwrite(gbreg_line, 1, rowstride, stdout);
#endif
gbreg_line += rowstride;
}
 
return 0;
}
 
static int
jbig2_decode_generic_template3_unopt(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
uint32_t CONTEXT;
int x,y;
bool bit;
 
/* this version is generic and easy to understand, but very slow */
 
for (y = 0; y < GBH; y++) {
for (x = 0; x < GBW; x++) {
CONTEXT = 0;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y) << 0;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0],
y + params->gbat[1]) << 4;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 6;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
}
return 0;
}
 
static void
copy_prev_row(Jbig2Image *image, int row)
{
if (!row) {
/* no previous row */
memset( image->data, 0, image->stride );
} else {
/* duplicate data from the previous row */
uint8_t *src = image->data + (row - 1) * image->stride;
memcpy( src + image->stride, src, image->stride );
}
}
 
static int
jbig2_decode_generic_template0_TPGDON(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
uint32_t CONTEXT;
int x, y;
bool bit;
int LTP = 0;
 
for (y = 0; y < GBH; y++)
{
LTP ^= jbig2_arith_decode(as, &GB_stats[0x9B25]);
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0],
y + params->gbat[1]) << 4;
CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 5;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 6;
CONTEXT |= jbig2_image_get_pixel(image, x , y - 1) << 7;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 9;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[2],
y + params->gbat[3]) << 10;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[4],
y + params->gbat[5]) << 11;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 12;
CONTEXT |= jbig2_image_get_pixel(image, x , y - 2) << 13;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6],
y + params->gbat[7]) << 15;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
copy_prev_row(image, y);
}
}
 
return 0;
}
 
static int
jbig2_decode_generic_template1_TPGDON(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
uint32_t CONTEXT;
int x, y;
bool bit;
int LTP = 0;
 
for (y = 0; y < GBH; y++) {
LTP ^= jbig2_arith_decode(as, &GB_stats[0x0795]);
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0],
y + params->gbat[1]) << 3;
CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 4;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
CONTEXT |= jbig2_image_get_pixel(image, x , y - 1) << 6;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 2) << 9;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 10;
CONTEXT |= jbig2_image_get_pixel(image, x , y - 2) << 11;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 12;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
copy_prev_row(image, y);
}
}
 
return 0;
}
 
static int
jbig2_decode_generic_template2_TPGDON(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
uint32_t CONTEXT;
int x, y;
bool bit;
int LTP = 0;
 
for (y = 0; y < GBH; y++) {
LTP ^= jbig2_arith_decode(as, &GB_stats[0xE5]);
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0],
y + params->gbat[1]) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 3;
CONTEXT |= jbig2_image_get_pixel(image, x , y - 1) << 4;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 5;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 6;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 7;
CONTEXT |= jbig2_image_get_pixel(image, x , y - 2) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 9;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
copy_prev_row(image, y);
}
}
 
return 0;
}
 
static int
jbig2_decode_generic_template3_TPGDON(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int GBW = image->width;
const int GBH = image->height;
uint32_t CONTEXT;
int x, y;
bool bit;
int LTP = 0;
 
for (y = 0; y < GBH; y++) {
LTP ^= jbig2_arith_decode(as, &GB_stats[0x0195]);
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0],
y + params->gbat[1]) << 4;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
CONTEXT |= jbig2_image_get_pixel(image, x , y - 1) << 6;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
copy_prev_row(image, y);
}
}
 
return 0;
}
 
static int
jbig2_decode_generic_region_TPGDON(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
switch (params->GBTEMPLATE) {
case 0:
return jbig2_decode_generic_template0_TPGDON(ctx, segment,
params, as, image, GB_stats);
case 1:
return jbig2_decode_generic_template1_TPGDON(ctx, segment,
params, as, image, GB_stats);
case 2:
return jbig2_decode_generic_template2_TPGDON(ctx, segment,
params, as, image, GB_stats);
case 3:
return jbig2_decode_generic_template3_TPGDON(ctx, segment,
params, as, image, GB_stats);
}
 
return -1;
}
 
/**
* jbig2_decode_generic_region: Decode a generic region.
* @ctx: The context for allocation and error reporting.
* @segment: A segment reference for error reporting.
* @params: Decoding parameter set.
* @as: Arithmetic decoder state.
* @image: Where to store the decoded data.
* @GB_stats: Arithmetic stats.
*
* Decodes a generic region, according to section 6.2. The caller should
* pass an already allocated Jbig2Image object for @image
*
* Because this API is based on an arithmetic decoding state, it is
* not suitable for MMR decoding.
*
* Return code: 0 on success.
**/
int
jbig2_decode_generic_region(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
const int8_t *gbat = params->gbat;
 
if (!params->MMR && params->TPGDON)
return jbig2_decode_generic_region_TPGDON(ctx, segment, params,
as, image, GB_stats);
 
if (!params->MMR && params->GBTEMPLATE == 0) {
if (gbat[0] == +3 && gbat[1] == -1 &&
gbat[2] == -3 && gbat[3] == -1 &&
gbat[4] == +2 && gbat[5] == -2 &&
gbat[6] == -2 && gbat[7] == -2)
return jbig2_decode_generic_template0(ctx, segment, params,
as, image, GB_stats);
else
return jbig2_decode_generic_template0_unopt(ctx, segment, params,
as, image, GB_stats);
} else if (!params->MMR && params->GBTEMPLATE == 1)
return jbig2_decode_generic_template1(ctx, segment, params,
as, image, GB_stats);
else if (!params->MMR && params->GBTEMPLATE == 2)
{
if (gbat[0] == 3 && gbat[1] == -1)
return jbig2_decode_generic_template2a(ctx, segment, params,
as, image, GB_stats);
else
return jbig2_decode_generic_template2(ctx, segment, params,
as, image, GB_stats);
}
else if (!params->MMR && params->GBTEMPLATE == 3) {
if (gbat[0] == 2 && gbat[1] == -1)
return jbig2_decode_generic_template3_unopt(ctx, segment, params,
as, image, GB_stats);
else
return jbig2_decode_generic_template3_unopt(ctx, segment, params,
as, image, GB_stats);
}
 
{
int i;
for (i = 0; i < 8; i++)
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"gbat[%d] = %d", i, params->gbat[i]);
}
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"decode_generic_region: MMR=%d, GBTEMPLATE=%d NYI",
params->MMR, params->GBTEMPLATE);
return -1;
}
 
/**
* Handler for immediate generic region segments
*/
int
jbig2_immediate_generic_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data)
{
Jbig2RegionSegmentInfo rsi;
byte seg_flags;
int8_t gbat[8];
int offset;
int gbat_bytes = 0;
Jbig2GenericRegionParams params;
int code;
Jbig2Image *image;
Jbig2WordStream *ws;
Jbig2ArithState *as;
Jbig2ArithCx *GB_stats = NULL;
 
/* 7.4.6 */
if (segment->data_length < 18)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
 
jbig2_get_region_segment_info(&rsi, segment_data);
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"generic region: %d x %d @ (%d, %d), flags = %02x",
rsi.width, rsi.height, rsi.x, rsi.y, rsi.flags);
 
/* 7.4.6.2 */
seg_flags = segment_data[17];
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"segment flags = %02x", seg_flags);
if ((seg_flags & 1) && (seg_flags & 6))
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"MMR is 1, but GBTEMPLATE is not 0");
 
/* 7.4.6.3 */
if (!(seg_flags & 1))
{
gbat_bytes = (seg_flags & 6) ? 2 : 8;
if (18 + gbat_bytes > segment->data_length)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
memcpy(gbat, segment_data + 18, gbat_bytes);
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"gbat: %d, %d", gbat[0], gbat[1]);
}
 
offset = 18 + gbat_bytes;
 
/* Table 34 */
params.MMR = seg_flags & 1;
params.GBTEMPLATE = (seg_flags & 6) >> 1;
params.TPGDON = (seg_flags & 8) >> 3;
params.USESKIP = 0;
memcpy (params.gbat, gbat, gbat_bytes);
 
image = jbig2_image_new(ctx, rsi.width, rsi.height);
if (image == NULL)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"unable to allocate generic image");
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"allocated %d x %d image buffer for region decode results",
rsi.width, rsi.height);
 
if (params.MMR)
{
code = jbig2_decode_generic_mmr(ctx, segment, &params,
segment_data + offset, segment->data_length - offset,
image);
}
else
{
int stats_size = jbig2_generic_stats_size(ctx, params.GBTEMPLATE);
GB_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GB_stats, 0, stats_size);
 
ws = jbig2_word_stream_buf_new(ctx,
segment_data + offset,
segment->data_length - offset);
as = jbig2_arith_new(ctx, ws);
code = jbig2_decode_generic_region(ctx, segment, &params,
as, image, GB_stats);
jbig2_free(ctx->allocator, as);
jbig2_word_stream_buf_free(ctx, ws);
 
jbig2_free(ctx->allocator, GB_stats);
}
 
jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page],
image, rsi.x, rsi.y, JBIG2_COMPOSE_OR);
jbig2_image_release(ctx, image);
 
return code;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_generic.h
0,0 → 1,62
/*
jbig2dec
 
Copyright (C) 2002-2004 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/**
* Headers for Generic and Generic Refinement region handling
**/
 
/* 6.4 Table 2 */
typedef struct {
bool MMR;
/* GBW */
/* GBH */
int GBTEMPLATE;
bool TPGDON;
bool USESKIP;
/* SKIP */
int8_t gbat[8];
} Jbig2GenericRegionParams;
 
/* return the appropriate context size for the given template */
int
jbig2_generic_stats_size(Jbig2Ctx *ctx, int template);
 
int
jbig2_decode_generic_region(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats);
 
 
/* 6.3 Table 6 */
typedef struct {
/* GRW */
/* GRH */
bool GRTEMPLATE;
Jbig2Image *reference;
int32_t DX, DY;
bool TPGRON;
int8_t grat[4];
} Jbig2RefinementRegionParams;
 
int
jbig2_decode_refinement_region(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2RefinementRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GB_stats);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_halftone.c
0,0 → 1,372
/*
jbig2dec
 
Copyright (C) 2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* JBIG2 Pattern Dictionary and Halftone Region decoding */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <string.h> /* memset() */
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_generic.h"
#include "jbig2_mmr.h"
 
typedef struct {
int n_patterns;
Jbig2Image **patterns;
int HPW, HPH;
} Jbig2PatternDict;
 
/* Table 24 */
typedef struct {
bool HDMMR;
uint32_t HDPW;
uint32_t HDPH;
uint32_t GRAYMAX;
int HDTEMPLATE;
} Jbig2PatternDictParams;
 
/* Table 33 */
typedef struct {
byte flags;
uint32_t HGW;
uint32_t HGH;
int32_t HGX;
int32_t HGY;
uint16_t HRX;
uint16_t HRY;
bool HMMR;
int HTEMPLATE;
bool HENABLESKIP;
Jbig2ComposeOp op;
bool HDEFPIXEL;
} Jbig2HalftoneRegionParams;
 
 
/**
* jbig2_hd_new: create a new dictionary from a collective bitmap
*/
Jbig2PatternDict *
jbig2_hd_new(Jbig2Ctx *ctx,
const Jbig2PatternDictParams *params,
Jbig2Image *image)
{
Jbig2PatternDict *new;
const int N = params->GRAYMAX + 1;
const int HPW = params->HDPW;
const int HPH = params->HDPH;
int i;
 
/* allocate a new struct */
new = (Jbig2PatternDict *)jbig2_alloc(ctx->allocator,
sizeof(Jbig2PatternDict));
if (new != NULL) {
new->patterns = (Jbig2Image **)jbig2_alloc(ctx->allocator,
N*sizeof(Jbig2Image*));
if (new->patterns == NULL) {
jbig2_free(ctx->allocator, new);
return NULL;
}
new->n_patterns = N;
new->HPW = HPW;
new->HPH = HPH;
 
/* 6.7.5(4) - copy out the individual pattern images */
for (i = 0; i < N; i++) {
new->patterns[i] = jbig2_image_new(ctx, HPW, HPH);
if (new->patterns[i] == NULL) {
int j;
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"failed to allocate pattern element image");
for (j = 0; j < i; j++)
jbig2_free(ctx->allocator, new->patterns[j]);
jbig2_free(ctx->allocator, new);
return NULL;
}
/* compose with the REPLACE operator; the source
will be clipped to the destintion, selecting the
proper sub image */
jbig2_image_compose(ctx, new->patterns[i], image,
-i * HPW, 0, JBIG2_COMPOSE_REPLACE);
}
}
 
return new;
}
 
/**
* jbig2_hd_release: release a pattern dictionary
*/
void
jbig2_hd_release(Jbig2Ctx *ctx, Jbig2PatternDict *dict)
{
int i;
 
if (dict == NULL) return;
for (i = 0; i < dict->n_patterns; i++)
if (dict->patterns[i]) jbig2_image_release(ctx, dict->patterns[i]);
jbig2_free(ctx->allocator, dict->patterns);
jbig2_free(ctx->allocator, dict);
}
 
/**
* jbig2_decode_pattern_dict: decode pattern dictionary data
*
* @ctx: jbig2 decoder context
* @segment: jbig2 segment (header) structure
* @params: parameters from the pattern dictionary header
* @data: pointer to text region data to be decoded
* @size: length of text region data
* @GB_stats: artimetic coding context to use
*
* Implements the patten dictionary decoding proceedure
* described in section 6.7 of the JBIG2 spec.
*
* returns: a pointer to the resulting dictionary on success
* returns: 0 on failure
**/
static Jbig2PatternDict *
jbig2_decode_pattern_dict(Jbig2Ctx *ctx, Jbig2Segment *segment,
const Jbig2PatternDictParams *params,
const byte *data, const size_t size,
Jbig2ArithCx *GB_stats)
{
Jbig2PatternDict *hd = NULL;
Jbig2Image *image;
Jbig2GenericRegionParams rparams;
int code;
 
/* allocate the collective image */
image = jbig2_image_new(ctx,
params->HDPW * (params->GRAYMAX + 1), params->HDPH);
if (image == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"failed to allocate collective bitmap for halftone dict!");
return NULL;
}
 
/* fill out the generic region decoder parameters */
rparams.MMR = params->HDMMR;
rparams.GBTEMPLATE = params->HDTEMPLATE;
rparams.TPGDON = 0; /* not used if HDMMR = 1 */
rparams.USESKIP = 0;
rparams.gbat[0] = -params->HDPW;
rparams.gbat[1] = 0;
rparams.gbat[2] = -3;
rparams.gbat[3] = -1;
rparams.gbat[4] = 2;
rparams.gbat[5] = -2;
rparams.gbat[6] = -2;
rparams.gbat[7] = -2;
 
if (params->HDMMR) {
code = jbig2_decode_generic_mmr(ctx, segment, &rparams,
data, size, image);
} else {
Jbig2WordStream *ws = jbig2_word_stream_buf_new(ctx, data, size);
Jbig2ArithState *as = jbig2_arith_new(ctx, ws);
 
code = jbig2_decode_generic_region(ctx, segment, &rparams,
as, image, GB_stats);
 
jbig2_free(ctx->allocator, as);
jbig2_word_stream_buf_free(ctx, ws);
}
if (code != 0) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"error decoding collective pattern dictionary bitmap!");
}
 
hd = jbig2_hd_new(ctx, params, image);
jbig2_image_release(ctx, image);
 
return hd;
}
 
/* 7.4.4 */
int
jbig2_pattern_dictionary(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data)
{
Jbig2PatternDictParams params;
Jbig2ArithCx *GB_stats = NULL;
byte flags;
int offset = 0;
 
/* 7.4.4.1 - Data header */
if (segment->data_length < 7) {
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
}
flags = segment_data[0];
params.HDMMR = flags & 1;
params.HDTEMPLATE = (flags & 6) >> 1;
params.HDPW = segment_data[1];
params.HDPH = segment_data[2];
params.GRAYMAX = jbig2_get_int32(segment_data + 3);
offset += 7;
 
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"pattern dictionary, flags=%02x, %d grays (%dx%d cell)",
flags, params.GRAYMAX + 1, params.HDPW, params.HDPH);
 
if (params.HDMMR && params.HDTEMPLATE) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"HDTEMPLATE is %d when HDMMR is %d, contrary to spec",
params.HDTEMPLATE, params.HDMMR);
}
if (flags & 0xf8) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"Reserved flag bits non-zero");
}
 
/* 7.4.4.2 */
if (!params.HDMMR) {
/* allocate and zero arithmetic coding stats */
int stats_size = jbig2_generic_stats_size(ctx, params.HDTEMPLATE);
GB_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GB_stats, 0, stats_size);
}
 
segment->result = jbig2_decode_pattern_dict(ctx, segment, &params,
segment_data + offset,
segment->data_length - offset, GB_stats);
 
/* todo: retain GB_stats? */
if (!params.HDMMR) {
jbig2_free(ctx->allocator, GB_stats);
}
 
return (segment->result != NULL) ? 0 : 1;
}
 
 
 
/**
* jbig2_decode_halftone_region: decode a halftone region
**/
int
jbig2_decode_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
Jbig2HalftoneRegionParams *params,
const byte *data, const size_t size,
Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
int code = 0;
 
/* todo: implement */
return code;
}
 
/**
* jbig2_halftone_region: read a halftone region segment header
**/
int
jbig2_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data)
{
int offset = 0;
Jbig2RegionSegmentInfo region_info;
Jbig2HalftoneRegionParams params;
Jbig2Image *image;
Jbig2ArithCx *GB_stats;
int code;
 
/* 7.4.5.1 */
if (segment->data_length < 17) goto too_short;
jbig2_get_region_segment_info(&region_info, segment_data);
offset += 17;
 
if (segment->data_length < 18) goto too_short;
 
/* 7.4.5.1.1 */
params.flags = segment_data[offset];
params.HMMR = params.flags & 1;
params.HTEMPLATE = (params.flags & 6) >> 1;
params.HENABLESKIP = (params.flags & 8) >> 3;
params.op = (params.flags & 0x70) >> 4;
params.HDEFPIXEL = (params.flags &0x80) >> 7;
offset += 1;
 
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"halftone region: %d x %d @ (%x,%d) flags=%02x",
region_info.width, region_info.height,
region_info.x, region_info.y, params.flags);
 
if (params.HMMR && params.HTEMPLATE) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"HTEMPLATE is %d when HMMR is %d, contrary to spec",
params.HTEMPLATE, params.HMMR);
}
if (params.HMMR && params.HENABLESKIP) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"HENABLESKIP is %d when HMMR is %d, contrary to spec",
params.HENABLESKIP, params.HMMR);
}
 
/* Figure 43 */
if (segment->data_length - offset < 16) goto too_short;
params.HGW = jbig2_get_int32(segment_data + offset);
params.HGH = jbig2_get_int32(segment_data + offset + 4);
params.HGX = jbig2_get_int32(segment_data + offset + 8);
params.HGY = jbig2_get_int32(segment_data + offset + 12);
offset += 16;
 
/* Figure 44 */
if (segment->data_length - offset < 4) goto too_short;
params.HRX = jbig2_get_int16(segment_data + offset);
params.HRY = jbig2_get_int16(segment_data + offset + 2);
offset += 4;
 
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
" grid %d x %d @ (%d.%d,%d.%d) vector (%d.%d,%d.%d)",
params.HGW, params.HGH,
params.HGX >> 8, params.HGX & 0xff,
params.HGY >> 8, params.HGY & 0xff,
params.HRX >> 8, params.HRX & 0xff,
params.HRY >> 8, params.HRY & 0xff);
 
/* 7.4.5.2.2 */
if (!params.HMMR) {
/* allocate and zero arithmetic coding stats */
int stats_size = jbig2_generic_stats_size(ctx, params.HTEMPLATE);
GB_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GB_stats, 0, stats_size);
}
 
image = jbig2_image_new(ctx, region_info.width, region_info.height);
if (image == NULL)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"unable to allocate halftone image");
 
code = jbig2_decode_halftone_region(ctx, segment, &params,
segment_data + offset, segment->data_length - offset,
image, GB_stats);
 
/* todo: retain GB_stats? */
if (!params.HMMR) {
jbig2_free(ctx->allocator, GB_stats);
}
 
return code;
 
too_short:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_huffman.c
0,0 → 1,480
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* Huffman table decoding procedures
-- See Annex B of the JBIG2 specification */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stdlib.h>
#include <string.h>
 
#ifdef JBIG2_DEBUG
#include <stdio.h>
#endif
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_huffman.h"
#include "jbig2_hufftab.h"
 
#define JBIG2_HUFFMAN_FLAGS_ISOOB 1
#define JBIG2_HUFFMAN_FLAGS_ISLOW 2
#define JBIG2_HUFFMAN_FLAGS_ISEXT 4
 
 
 
struct _Jbig2HuffmanState {
/* The current bit offset is equal to (offset * 8) + offset_bits.
The MSB of this_word is the current bit offset. The MSB of next_word
is (offset + 4) * 8. */
uint32_t this_word;
uint32_t next_word;
int offset_bits;
int offset;
 
Jbig2WordStream *ws;
};
 
 
/** Allocate and initialize a new huffman coding state
* the returned pointer can simply be freed; this does
* not affect the associated Jbig2WordStream.
*/
Jbig2HuffmanState *
jbig2_huffman_new (Jbig2Ctx *ctx, Jbig2WordStream *ws)
{
Jbig2HuffmanState *result;
 
result = (Jbig2HuffmanState *)jbig2_alloc(ctx->allocator,
sizeof(Jbig2HuffmanState));
 
if (result != NULL) {
result->offset = 0;
result->offset_bits = 0;
result->this_word = ws->get_next_word (ws, 0);
result->next_word = ws->get_next_word (ws, 4);
 
result->ws = ws;
}
 
return result;
}
 
/** Free an allocated huffman coding state.
* This just calls jbig2_free() if the pointer is not NULL
*/
void
jbig2_huffman_free (Jbig2Ctx *ctx, Jbig2HuffmanState *hs)
{
if (hs != NULL) free(hs);
return;
}
 
/** debug routines **/
#ifdef JBIG2_DEBUG
 
/** print current huffman state */
void jbig2_dump_huffman_state(Jbig2HuffmanState *hs) {
fprintf(stderr, "huffman state %08x %08x offset %d.%d\n",
hs->this_word, hs->next_word, hs->offset, hs->offset_bits);
}
 
/** print the binary string we're reading from */
void jbig2_dump_huffman_binary(Jbig2HuffmanState *hs)
{
const uint32_t word = hs->this_word;
int i;
 
fprintf(stderr, "huffman binary ");
for (i = 31; i >= 0; i--)
fprintf(stderr, ((word >> i) & 1) ? "1" : "0");
fprintf(stderr, "\n");
}
 
#endif /* JBIG2_DEBUG */
 
/** Skip bits up to the next byte boundary
*/
void
jbig2_huffman_skip(Jbig2HuffmanState *hs)
{
int bits = hs->offset_bits & 7;
 
if (bits) {
bits = 8 - bits;
hs->offset_bits += bits;
hs->this_word = (hs->this_word << bits) |
(hs->next_word >> (32 - hs->offset_bits));
}
 
if (hs->offset_bits >= 32) {
Jbig2WordStream *ws = hs->ws;
hs->this_word = hs->next_word;
hs->offset += 4;
hs->next_word = ws->get_next_word (ws, hs->offset + 4);
hs->offset_bits -= 32;
if (hs->offset_bits) {
hs->this_word = (hs->this_word << hs->offset_bits) |
(hs->next_word >> (32 - hs->offset_bits));
}
}
}
 
/* skip ahead a specified number of bytes in the word stream
*/
void jbig2_huffman_advance(Jbig2HuffmanState *hs, int offset)
{
Jbig2WordStream *ws = hs->ws;
 
hs->offset += offset & ~3;
hs->offset_bits += (offset & 3) << 3;
if (hs->offset_bits >= 32) {
hs->offset += 4;
hs->offset_bits -= 32;
}
hs->this_word = ws->get_next_word (ws, hs->offset);
hs->next_word = ws->get_next_word (ws, hs->offset + 4);
if (hs->offset_bits > 0)
hs->this_word = (hs->this_word << hs->offset_bits) |
(hs->next_word >> (32 - hs->offset_bits));
}
 
/* return the offset of the huffman decode pointer (in bytes)
* from the beginning of the WordStream
*/
int
jbig2_huffman_offset(Jbig2HuffmanState *hs)
{
return hs->offset + (hs->offset_bits >> 3);
}
 
/* read a number of bits directly from the huffman state
* without decoding against a table
*/
int32_t
jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits)
{
uint32_t this_word = hs->this_word;
int32_t result;
 
result = this_word >> (32 - bits);
hs->offset_bits += bits;
if (hs->offset_bits >= 32) {
hs->offset += 4;
hs->offset_bits -= 32;
hs->this_word = hs->next_word;
hs->next_word = hs->ws->get_next_word(hs->ws, hs->offset + 4);
if (hs->offset_bits) {
hs->this_word = (hs->this_word << hs->offset_bits) |
(hs->next_word >> (32 - hs->offset_bits));
} else {
hs->this_word = (hs->this_word << hs->offset_bits);
}
} else {
hs->this_word = (this_word << bits) |
(hs->next_word >> (32 - hs->offset_bits));
}
 
return result;
}
 
int32_t
jbig2_huffman_get (Jbig2HuffmanState *hs,
const Jbig2HuffmanTable *table, bool *oob)
{
Jbig2HuffmanEntry *entry;
byte flags;
int offset_bits = hs->offset_bits;
uint32_t this_word = hs->this_word;
uint32_t next_word;
int RANGELEN;
int32_t result;
 
for (;;)
{
int log_table_size = table->log_table_size;
int PREFLEN;
 
entry = &table->entries[this_word >> (32 - log_table_size)];
flags = entry->flags;
PREFLEN = entry->PREFLEN;
 
next_word = hs->next_word;
offset_bits += PREFLEN;
if (offset_bits >= 32)
{
Jbig2WordStream *ws = hs->ws;
this_word = next_word;
hs->offset += 4;
next_word = ws->get_next_word (ws, hs->offset + 4);
offset_bits -= 32;
hs->next_word = next_word;
PREFLEN = offset_bits;
}
if (PREFLEN)
this_word = (this_word << PREFLEN) |
(next_word >> (32 - offset_bits));
if (flags & JBIG2_HUFFMAN_FLAGS_ISEXT)
{
table = entry->u.ext_table;
}
else
break;
}
result = entry->u.RANGELOW;
RANGELEN = entry->RANGELEN;
if (RANGELEN > 0)
{
int32_t HTOFFSET;
 
HTOFFSET = this_word >> (32 - RANGELEN);
if (flags & JBIG2_HUFFMAN_FLAGS_ISLOW)
result -= HTOFFSET;
else
result += HTOFFSET;
 
offset_bits += RANGELEN;
if (offset_bits >= 32)
{
Jbig2WordStream *ws = hs->ws;
this_word = next_word;
hs->offset += 4;
next_word = ws->get_next_word (ws, hs->offset + 4);
offset_bits -= 32;
hs->next_word = next_word;
RANGELEN = offset_bits;
}
if (RANGELEN)
this_word = (this_word << RANGELEN) |
(next_word >> (32 - offset_bits));
}
 
hs->this_word = this_word;
hs->offset_bits = offset_bits;
 
if (oob != NULL)
*oob = (flags & JBIG2_HUFFMAN_FLAGS_ISOOB);
 
return result;
}
 
/* TODO: more than 8 bits here is wasteful of memory. We have support
for sub-trees in jbig2_huffman_get() above, but don't use it here.
We should, and then revert to 8 bits */
#define LOG_TABLE_SIZE_MAX 16
 
/** Build an in-memory representation of a Huffman table from the
* set of template params provided by the spec or a table segment
*/
Jbig2HuffmanTable *
jbig2_build_huffman_table (Jbig2Ctx *ctx, const Jbig2HuffmanParams *params)
{
int *LENCOUNT;
int LENMAX = -1;
const int lencountsize = 256 * sizeof(*LENCOUNT);
const Jbig2HuffmanLine *lines = params->lines;
int n_lines = params->n_lines;
int i, j;
int max_j;
int log_table_size = 0;
Jbig2HuffmanTable *result;
Jbig2HuffmanEntry *entries;
int CURLEN;
int firstcode = 0;
int CURCODE;
int CURTEMP;
 
LENCOUNT = jbig2_alloc(ctx->allocator, lencountsize);
if (LENCOUNT == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"couldn't allocate storage for huffman histogram");
return NULL;
}
memset(LENCOUNT, 0, lencountsize);
 
/* B.3, 1. */
for (i = 0; i < params->n_lines; i++)
{
int PREFLEN = lines[i].PREFLEN;
int lts;
 
if (PREFLEN > LENMAX)
{
for (j = LENMAX + 1; j < PREFLEN + 1; j++)
LENCOUNT[j] = 0;
LENMAX = PREFLEN;
}
LENCOUNT[PREFLEN]++;
 
lts = PREFLEN + lines[i].RANGELEN;
if (lts > LOG_TABLE_SIZE_MAX)
lts = PREFLEN;
if (lts <= LOG_TABLE_SIZE_MAX && log_table_size < lts)
log_table_size = lts;
}
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
"constructing huffman table log size %d", log_table_size);
max_j = 1 << log_table_size;
 
result = (Jbig2HuffmanTable *)jbig2_alloc(ctx->allocator, sizeof(Jbig2HuffmanTable));
result->log_table_size = log_table_size;
entries = (Jbig2HuffmanEntry *)jbig2_alloc(ctx->allocator, max_j * sizeof(Jbig2HuffmanEntry));
result->entries = entries;
 
LENCOUNT[0] = 0;
 
for (CURLEN = 1; CURLEN <= LENMAX; CURLEN++)
{
int shift = log_table_size - CURLEN;
 
/* B.3 3.(a) */
firstcode = (firstcode + LENCOUNT[CURLEN - 1]) << 1;
CURCODE = firstcode;
/* B.3 3.(b) */
for (CURTEMP = 0; CURTEMP < n_lines; CURTEMP++)
{
int PREFLEN = lines[CURTEMP].PREFLEN;
if (PREFLEN == CURLEN)
{
int RANGELEN = lines[CURTEMP].RANGELEN;
int start_j = CURCODE << shift;
int end_j = (CURCODE + 1) << shift;
byte eflags = 0;
 
if (end_j > max_j) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"ran off the end of the entries table! (%d >= %d)",
end_j, max_j);
jbig2_free(ctx->allocator, result->entries);
jbig2_free(ctx->allocator, result);
jbig2_free(ctx->allocator, LENCOUNT);
return NULL;
}
/* todo: build extension tables */
if (params->HTOOB && CURTEMP == n_lines - 1)
eflags |= JBIG2_HUFFMAN_FLAGS_ISOOB;
if (CURTEMP == n_lines - (params->HTOOB ? 3 : 2))
eflags |= JBIG2_HUFFMAN_FLAGS_ISLOW;
if (PREFLEN + RANGELEN > LOG_TABLE_SIZE_MAX) {
for (j = start_j; j < end_j; j++) {
entries[j].u.RANGELOW = lines[CURTEMP].RANGELOW;
entries[j].PREFLEN = PREFLEN;
entries[j].RANGELEN = RANGELEN;
entries[j].flags = eflags;
}
} else {
for (j = start_j; j < end_j; j++) {
int32_t HTOFFSET = (j >> (shift - RANGELEN)) &
((1 << RANGELEN) - 1);
if (eflags & JBIG2_HUFFMAN_FLAGS_ISLOW)
entries[j].u.RANGELOW = lines[CURTEMP].RANGELOW -
HTOFFSET;
else
entries[j].u.RANGELOW = lines[CURTEMP].RANGELOW +
HTOFFSET;
entries[j].PREFLEN = PREFLEN + RANGELEN;
entries[j].RANGELEN = 0;
entries[j].flags = eflags;
}
}
CURCODE++;
}
}
}
 
jbig2_free(ctx->allocator, LENCOUNT);
 
return result;
}
 
/** Free the memory associated with the representation of table */
void
jbig2_release_huffman_table (Jbig2Ctx *ctx, Jbig2HuffmanTable *table)
{
if (table != NULL) {
jbig2_free(ctx->allocator, table->entries);
jbig2_free(ctx->allocator, table);
}
return;
}
 
#ifdef TEST
#include <stdio.h>
 
/* a test bitstream, and a list of the table indicies
to use in decoding it. 1 = table B.1 (A), 2 = table B.2 (B), and so on */
/* this test stream should decode to { 8, 5, oob, 8 } */
 
const byte test_stream[] = { 0xe9, 0xcb, 0xf4, 0x00 };
const byte test_tabindex[] = { 4, 2, 2, 1 };
 
static uint32_t
test_get_word (Jbig2WordStream *self, int offset)
{
/* assume test_stream[] is at least 4 bytes */
if (offset+3 > sizeof(test_stream))
return 0;
else
return ( (test_stream[offset] << 24) |
(test_stream[offset+1] << 16) |
(test_stream[offset+2] << 8) |
(test_stream[offset+3]) );
}
 
int
main (int argc, char **argv)
{
Jbig2Ctx *ctx;
Jbig2HuffmanTable *tables[5];
Jbig2HuffmanState *hs;
Jbig2WordStream ws;
bool oob;
int32_t code;
 
ctx = jbig2_ctx_new(NULL, 0, NULL, NULL, NULL);
 
tables[0] = NULL;
tables[1] = jbig2_build_huffman_table (ctx, &jbig2_huffman_params_A);
tables[2] = jbig2_build_huffman_table (ctx, &jbig2_huffman_params_B);
tables[3] = NULL;
tables[4] = jbig2_build_huffman_table (ctx, &jbig2_huffman_params_D);
ws.get_next_word = test_get_word;
hs = jbig2_huffman_new (ctx, &ws);
 
printf("testing jbig2 huffmann decoding...");
printf("\t(should be 8 5 (oob) 8)\n");
 
{
int i;
int sequence_length = sizeof(test_tabindex);
 
for (i = 0; i < sequence_length; i++) {
code = jbig2_huffman_get (hs, tables[test_tabindex[i]], &oob);
if (oob) printf("(oob) ");
else printf("%d ", code);
}
}
 
printf("\n");
 
jbig2_ctx_free(ctx);
 
return 0;
}
#endif
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_huffman.h
0,0 → 1,105
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifndef JBIG2_HUFFMAN_H
#define JBIG2_HUFFMAN_H
 
/* Huffman coder interface */
 
typedef struct _Jbig2HuffmanEntry Jbig2HuffmanEntry;
typedef struct _Jbig2HuffmanState Jbig2HuffmanState;
typedef struct _Jbig2HuffmanTable Jbig2HuffmanTable;
typedef struct _Jbig2HuffmanParams Jbig2HuffmanParams;
 
struct _Jbig2HuffmanEntry {
union {
int32_t RANGELOW;
Jbig2HuffmanTable *ext_table;
} u;
byte PREFLEN;
byte RANGELEN;
byte flags;
};
 
struct _Jbig2HuffmanTable {
int log_table_size;
Jbig2HuffmanEntry *entries;
};
 
typedef struct _Jbig2HuffmanLine Jbig2HuffmanLine;
 
struct _Jbig2HuffmanLine {
int PREFLEN;
int RANGELEN;
int RANGELOW;
};
 
struct _Jbig2HuffmanParams {
bool HTOOB;
int n_lines;
const Jbig2HuffmanLine *lines;
};
 
Jbig2HuffmanState *
jbig2_huffman_new (Jbig2Ctx *ctx, Jbig2WordStream *ws);
 
void
jbig2_huffman_free (Jbig2Ctx *ctx, Jbig2HuffmanState *hs);
 
void
jbig2_huffman_skip(Jbig2HuffmanState *hs);
 
void jbig2_huffman_advance(Jbig2HuffmanState *hs, int offset);
 
int
jbig2_huffman_offset(Jbig2HuffmanState *hs);
 
int32_t
jbig2_huffman_get (Jbig2HuffmanState *hs,
const Jbig2HuffmanTable *table, bool *oob);
 
int32_t
jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits);
 
#ifdef JBIG2_DEBUG
void jbig2_dump_huffman_state(Jbig2HuffmanState *hs);
void jbig2_dump_huffman_binary(Jbig2HuffmanState *hs);
#endif
 
Jbig2HuffmanTable *
jbig2_build_huffman_table (Jbig2Ctx *ctx, const Jbig2HuffmanParams *params);
 
void
jbig2_release_huffman_table (Jbig2Ctx *ctx, Jbig2HuffmanTable *table);
 
/* standard Huffman templates defined by the specification */
extern const Jbig2HuffmanParams jbig2_huffman_params_A; /* Table B.1 */
extern const Jbig2HuffmanParams jbig2_huffman_params_B; /* Table B.2 */
extern const Jbig2HuffmanParams jbig2_huffman_params_C; /* Table B.3 */
extern const Jbig2HuffmanParams jbig2_huffman_params_D; /* Table B.4 */
extern const Jbig2HuffmanParams jbig2_huffman_params_E; /* Table B.5 */
extern const Jbig2HuffmanParams jbig2_huffman_params_F; /* Table B.6 */
extern const Jbig2HuffmanParams jbig2_huffman_params_G; /* Table B.7 */
extern const Jbig2HuffmanParams jbig2_huffman_params_H; /* Table B.8 */
extern const Jbig2HuffmanParams jbig2_huffman_params_I; /* Table B.9 */
extern const Jbig2HuffmanParams jbig2_huffman_params_J; /* Table B.10 */
extern const Jbig2HuffmanParams jbig2_huffman_params_K; /* Table B.11 */
extern const Jbig2HuffmanParams jbig2_huffman_params_L; /* Table B.12 */
extern const Jbig2HuffmanParams jbig2_huffman_params_M; /* Table B.13 */
extern const Jbig2HuffmanParams jbig2_huffman_params_N; /* Table B.14 */
extern const Jbig2HuffmanParams jbig2_huffman_params_O; /* Table B.15 */
 
 
#endif /* JBIG2_HUFFMAN_H */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_hufftab.h
0,0 → 1,335
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* predefined Huffman table definitions
-- See Annex B of the JBIG2 specification */
 
#ifndef JBIG2_HUFFTAB_H
#define JBIG2_HUFFTAB_H
 
/* types are in jbig2_huffman.h, you must include that first */
 
 
/* Table B.1 */
const Jbig2HuffmanLine
jbig2_huffman_lines_A[] = {
{ 1, 4, 0 },
{ 2, 8, 16 },
{ 3, 16, 272 },
{ 0, 32, -1 }, /* low */
{ 3, 32, 65808 } /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_A = { FALSE, 5, jbig2_huffman_lines_A };
 
/* Table B.2 */
const Jbig2HuffmanLine
jbig2_huffman_lines_B[] = {
{ 1, 0, 0 },
{ 2, 0, 1 },
{ 3, 0, 2 },
{ 4, 3, 3 },
{ 5, 6, 11 },
{ 0, 32, -1 }, /* low */
{ 6, 32, 75 }, /* high */
{ 6, 0, 0 }
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_B = { TRUE, 8, jbig2_huffman_lines_B };
 
/* Table B.3 */
const Jbig2HuffmanLine
jbig2_huffman_lines_C[] = {
{ 8, 8, -256 },
{ 1, 0, 0 },
{ 2, 0, 1 },
{ 3, 0, 2 },
{ 4, 3, 3 },
{ 5, 6, 11 },
{ 8, 32, -257 }, /* low */
{ 7, 32, 75 }, /* high */
{ 6, 0, 0 } /* OOB */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_C = { TRUE, 9, jbig2_huffman_lines_C };
 
/* Table B.4 */
const Jbig2HuffmanLine
jbig2_huffman_lines_D[] = {
{ 1, 0, 1 },
{ 2, 0, 2 },
{ 3, 0, 3 },
{ 4, 3, 4 },
{ 5, 6, 12 },
{ 0, 32, -1 }, /* low */
{ 5, 32, 76 }, /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_D = { FALSE, 7, jbig2_huffman_lines_D };
 
/* Table B.5 */
const Jbig2HuffmanLine
jbig2_huffman_lines_E[] = {
{7, 8, -255},
{1, 0, 1},
{2, 0, 2},
{3, 0, 3},
{4, 3, 4},
{5, 6, 12},
{7, 32, -256}, /* low */
{6, 32, 76} /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_E = { FALSE, 8, jbig2_huffman_lines_E };
 
/* Table B.6 */
const Jbig2HuffmanLine
jbig2_huffman_lines_F[] = {
{5, 10, -2048},
{4, 9, -1024},
{4, 8, -512},
{4, 7, -256},
{5, 6, -128},
{5, 5, -64},
{4, 5, -32},
{2, 7, 0},
{3, 7, 128},
{3, 8, 256},
{4, 9, 512},
{4, 10, 1024},
{6, 32, -2049}, /* low */
{6, 32, 2048} /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_F = { FALSE, 14, jbig2_huffman_lines_F };
 
/* Table B.7 */
const Jbig2HuffmanLine
jbig2_huffman_lines_G[] = {
{4, 9, -1024},
{3, 8, -512},
{4, 7, -256},
{5, 6, -128},
{5, 5, -64},
{4, 5, -32},
{4, 5, 0},
{5, 5, 32},
{5, 6, 64},
{4, 7, 128},
{3, 8, 256},
{3, 9, 512},
{3, 10, 1024},
{5, 32, -1025}, /* low */
{5, 32, 2048} /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_G = { FALSE, 15, jbig2_huffman_lines_G };
 
/* Table B.8 */
const Jbig2HuffmanLine
jbig2_huffman_lines_H[] = {
{8, 3, -15},
{9, 1, -7},
{8, 1, -5},
{9, 0, -3},
{7, 0, -2},
{4, 0, -1},
{2, 1, 0},
{5, 0, 2},
{6, 0, 3},
{3, 4, 4},
{6, 1, 20},
{4, 4, 22},
{4, 5, 38},
{5, 6, 70},
{5, 7, 134},
{6, 7, 262},
{7, 8, 390},
{6, 10, 646},
{9, 32, -16}, /* low */
{9, 32, 1670}, /* high */
{2, 0, 0} /* OOB */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_H = { TRUE, 21, jbig2_huffman_lines_H };
 
/* Table B.9 */
const Jbig2HuffmanLine
jbig2_huffman_lines_I[] = {
{8, 4, -31},
{9, 2, -15},
{8, 2, -11},
{9, 1, -7},
{7, 1, -5},
{4, 1, -3},
{3, 1, -1},
{3, 1, 1},
{5, 1, 3},
{6, 1, 5},
{3, 5, 7},
{6, 2, 39},
{4, 5, 43},
{4, 6, 75},
{5, 7, 139},
{5, 8, 267},
{6, 8, 523},
{7, 9, 779},
{6, 11, 1291},
{9, 32, -32}, /* low */
{9, 32, 3339}, /* high */
{2, 0, 0} /* OOB */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_I = { TRUE, 22, jbig2_huffman_lines_I };
 
/* Table B.10 */
const Jbig2HuffmanLine
jbig2_huffman_lines_J[] = {
{7, 4, -21},
{8, 0, -5},
{7, 0, -4},
{5, 0, -3},
{2, 2, -2},
{5, 0, 2},
{6, 0, 3},
{7, 0, 4},
{8, 0, 5},
{2, 6, 6},
{5, 5, 70},
{6, 5, 102},
{6, 6, 134},
{6, 7, 198},
{6, 8, 326},
{6, 9, 582},
{6, 10, 1094},
{7, 11, 2118},
{8, 32, -22}, /* low */
{8, 32, 4166}, /* high */
{2, 0, 0} /* OOB */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_J = { TRUE, 21, jbig2_huffman_lines_J };
 
/* Table B.11 */
const Jbig2HuffmanLine
jbig2_huffman_lines_K[] = {
{1, 0, 1},
{2, 1, 2},
{4, 0, 3},
{4, 1, 5},
{5, 1, 7},
{5, 2, 9},
{6, 2, 13},
{7, 2, 17},
{7, 3, 21},
{7, 4, 29},
{7, 5, 45},
{7, 6, 77},
{7, 32, 141} /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_K = { FALSE, 13, jbig2_huffman_lines_K };
 
/* Table B.12 */
const Jbig2HuffmanLine
jbig2_huffman_lines_L[] = {
{1, 0, 1},
{2, 0, 2},
{3, 1, 3},
{5, 0, 5},
{5, 1, 6},
{6, 1, 8},
{7, 0, 10},
{7, 1, 11},
{7, 2, 13},
{7, 3, 17},
{7, 4, 25},
{8, 5, 41},
{8, 32, 73}
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_L = { FALSE, 13, jbig2_huffman_lines_L };
 
 
/* Table B.13 */
const Jbig2HuffmanLine
jbig2_huffman_lines_M[] = {
{1, 0, 1},
{3, 0, 2},
{4, 0, 3},
{5, 0, 4},
{4, 1, 5},
{3, 3, 7},
{6, 1, 15},
{6, 2, 17},
{6, 3, 21},
{6, 4, 29},
{6, 5, 45},
{7, 6, 77},
{7, 32, 141} /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_M = { FALSE, 13, jbig2_huffman_lines_M };
 
/* Table B.14 */
const Jbig2HuffmanLine
jbig2_huffman_lines_N[] = {
{ 3, 0, -2 },
{ 3, 0, -1 },
{ 1, 0, 0 },
{ 3, 3, 1 },
{ 3, 6, 2 },
{ 0, 32, -1 }, /* low */
{ 0, 32, 3 }, /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_N = { FALSE, 7, jbig2_huffman_lines_N };
 
/* Table B.15 */
const Jbig2HuffmanLine
jbig2_huffman_lines_O[] = {
{7, 4, -24},
{6, 2, -8},
{5, 1, -4},
{4, 0, -2},
{3, 0, -1},
{1, 0, 0},
{3, 0, 1},
{4, 0, 2},
{5, 1, 3},
{6, 2, 5},
{7, 4, 9},
{7, 32, -25}, /* low */
{7, 32, 25} /* high */
};
 
const Jbig2HuffmanParams
jbig2_huffman_params_O = { FALSE, 13, jbig2_huffman_lines_O };
 
#endif /* JBIG2_HUFFTAB_H */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_image.c
0,0 → 1,313
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* memcpy() */
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_image.h"
 
 
/* allocate a Jbig2Image structure and its associated bitmap */
Jbig2Image* jbig2_image_new(Jbig2Ctx *ctx, int width, int height)
{
Jbig2Image *image;
int stride;
 
image = (Jbig2Image *)jbig2_alloc(ctx->allocator, sizeof(*image));
if (image == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"could not allocate image structure");
return NULL;
}
 
stride = ((width - 1) >> 3) + 1; /* generate a byte-aligned stride */
image->data = (uint8_t *)jbig2_alloc(ctx->allocator, stride*height);
if (image->data == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"could not allocate image data buffer! [%d bytes]\n", stride*height);
jbig2_free(ctx->allocator, image);
return NULL;
}
 
image->width = width;
image->height = height;
image->stride = stride;
image->refcount = 1;
 
return image;
}
 
/* clone an image pointer by bumping its reference count */
Jbig2Image* jbig2_image_clone(Jbig2Ctx *ctx, Jbig2Image *image)
{
image->refcount++;
return image;
}
 
/* release an image pointer, freeing it it appropriate */
void jbig2_image_release(Jbig2Ctx *ctx, Jbig2Image *image)
{
image->refcount--;
if (!image->refcount) jbig2_image_free(ctx, image);
}
 
/* free a Jbig2Image structure and its associated memory */
void jbig2_image_free(Jbig2Ctx *ctx, Jbig2Image *image)
{
jbig2_free(ctx->allocator, image->data);
jbig2_free(ctx->allocator, image);
}
 
/* resize a Jbig2Image */
Jbig2Image *jbig2_image_resize(Jbig2Ctx *ctx, Jbig2Image *image,
int width, int height)
{
if (width == image->width) {
/* use the same stride, just change the length */
image->data = jbig2_realloc(ctx->allocator,
image->data, image->stride*height);
if (image->data == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"could not resize image buffer!");
return NULL;
}
if (height > image->height) {
memset(image->data + image->height*image->stride,
0, (height - image->height)*image->stride);
}
image->height = height;
 
} else {
/* we must allocate a new image buffer and copy */
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
"jbig2_image_resize called with a different width (NYI)");
}
 
return NULL;
}
 
/* composite one jbig2_image onto another
slow but general version */
int jbig2_image_compose_unopt(Jbig2Ctx *ctx,
Jbig2Image *dst, Jbig2Image *src,
int x, int y, Jbig2ComposeOp op)
{
int i, j;
int sw = src->width;
int sh = src->height;
int sx = 0;
int sy = 0;
 
/* clip to the dst image boundaries */
if (x < 0) { sx += -x; sw -= -x; x = 0; }
if (y < 0) { sy += -y; sh -= -y; y = 0; }
if (x + sw >= dst->width) sw = dst->width - x;
if (y + sh >= dst->height) sh = dst->height - y;
 
switch (op) {
case JBIG2_COMPOSE_OR:
for (j = 0; j < sh; j++) {
for (i = 0; i < sw; i++) {
jbig2_image_set_pixel(dst, i+x, j+y,
jbig2_image_get_pixel(src, i+sx, j+sy) |
jbig2_image_get_pixel(dst, i+x, j+y));
}
}
break;
case JBIG2_COMPOSE_AND:
for (j = 0; j < sh; j++) {
for (i = 0; i < sw; i++) {
jbig2_image_set_pixel(dst, i+x, j+y,
jbig2_image_get_pixel(src, i+sx, j+sy) &
jbig2_image_get_pixel(dst, i+x, j+y));
}
}
break;
case JBIG2_COMPOSE_XOR:
for (j = 0; j < sh; j++) {
for (i = 0; i < sw; i++) {
jbig2_image_set_pixel(dst, i+x, j+y,
jbig2_image_get_pixel(src, i+sx, j+sy) ^
jbig2_image_get_pixel(dst, i+x, j+y));
}
}
break;
case JBIG2_COMPOSE_XNOR:
for (j = 0; j < sh; j++) {
for (i = 0; i < sw; i++) {
jbig2_image_set_pixel(dst, i+x, j+y,
~(jbig2_image_get_pixel(src, i+sx, j+sy) ^
jbig2_image_get_pixel(dst, i+x, j+y)));
}
}
break;
case JBIG2_COMPOSE_REPLACE:
for (j = 0; j < sh; j++) {
for (i = 0; i < sw; i++) {
jbig2_image_set_pixel(dst, i+x, j+y,
jbig2_image_get_pixel(src, i+sx, j+sy));
}
}
break;
}
 
return 0;
}
 
/* composite one jbig2_image onto another */
int jbig2_image_compose(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src,
int x, int y, Jbig2ComposeOp op)
{
int i, j;
int w, h;
int leftbyte, rightbyte;
int shift;
uint8_t *s, *ss;
uint8_t *d, *dd;
uint8_t mask, rightmask;
 
if (op != JBIG2_COMPOSE_OR) {
/* hand off the the general routine */
return jbig2_image_compose_unopt(ctx, dst, src, x, y, op);
}
 
/* clip */
w = src->width;
h = src->height;
ss = src->data;
/* FIXME: this isn't sufficient for the < 0 cases */
if (x < 0) { w += x; x = 0; }
if (y < 0) { h += y; y = 0; }
w = (x + w < dst->width) ? w : dst->width - x;
h = (y + h < dst->height) ? h : dst->height - y;
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
"compositing %dx%d at (%d, %d) after clipping\n",
w, h, x, y);
#endif
 
#if 0
/* special case complete/strip replacement */
/* disabled because it's only safe to do when the destination
buffer is all-blank. */
if ((x == 0) && (w == src->width)) {
memcpy(dst->data + y*dst->stride, src->data, h*src->stride);
return 0;
}
#endif
 
leftbyte = x >> 3;
rightbyte = (x + w - 1) >> 3;
shift = x & 7;
 
/* general OR case */
s = ss;
d = dd = dst->data + y*dst->stride + leftbyte;
if (leftbyte == rightbyte) {
mask = 0x100 - (0x100 >> w);
for (j = 0; j < h; j++) {
*d |= (*s & mask) >> shift;
d += dst->stride;
s += src->stride;
}
} else if (shift == 0) {
rightmask = (w & 7) ? 0x100 - (1 << (8 - (w & 7))) : 0xFF;
for (j = 0; j < h; j++) {
for (i = leftbyte; i < rightbyte; i++)
*d++ |= *s++;
*d |= *s & rightmask;
d = (dd += dst->stride);
s = (ss += src->stride);
}
} else {
bool overlap = (((w + 7) >> 3) < ((x + w + 7) >> 3) - (x >> 3));
mask = 0x100 - (1 << shift);
if (overlap)
rightmask = (0x100 - (0x100 >> ((x + w) & 7))) >> (8 - shift);
else
rightmask = 0x100 - (0x100 >> (w & 7));
for (j = 0; j < h; j++) {
*d++ |= (*s & mask) >> shift;
for(i = leftbyte; i < rightbyte - 1; i++) {
*d |= ((*s++ & ~mask) << (8 - shift));
*d++ |= ((*s & mask) >> shift);
}
if (overlap)
*d |= (*s & rightmask) << (8 - shift);
else
*d |= ((s[0] & ~mask) << (8 - shift)) |
((s[1] & rightmask) >> shift);
d = (dd += dst->stride);
s = (ss += src->stride);
}
}
 
return 0;
}
 
 
/* initialize an image bitmap to a constant value */
void jbig2_image_clear(Jbig2Ctx *ctx, Jbig2Image *image, int value)
{
const uint8_t fill = value ? 0xFF : 0x00;
 
memset(image->data, fill, image->stride*image->height);
}
 
/* look up a pixel value in an image.
returns 0 outside the image frame for the convenience of
the template code
*/
int jbig2_image_get_pixel(Jbig2Image *image, int x, int y)
{
const int w = image->width;
const int h = image->height;
const int byte = (x >> 3) + y*image->stride;
const int bit = 7 - (x & 7);
 
if ((x < 0) || (x >= w)) return 0;
if ((y < 0) || (y >= h)) return 0;
 
return ((image->data[byte]>>bit) & 1);
}
 
/* set an individual pixel value in an image */
int jbig2_image_set_pixel(Jbig2Image *image, int x, int y, bool value)
{
const int w = image->width;
const int h = image->height;
int scratch, mask;
int bit, byte;
 
if ((x < 0) || (x >= w)) return 0;
if ((y < 0) || (y >= h)) return 0;
 
byte = (x >> 3) + y*image->stride;
bit = 7 - (x & 7);
mask = (1 << bit) ^ 0xff;
 
scratch = image->data[byte] & mask;
image->data[byte] = scratch | (value << bit);
 
return 1;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_image.h
0,0 → 1,38
/*
jbig2dec
 
Copyright (C) 2001-2002 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
 
#ifndef _JBIG2_IMAGE_H
#define _JBIG2_IMAGE_H
 
int jbig2_image_get_pixel(Jbig2Image *image, int x, int y);
int jbig2_image_set_pixel(Jbig2Image *image, int x, int y, int value);
 
/* routines for dumping the image data in various formats */
/* FIXME: should these be in the client instead? */
 
#include <stdio.h>
 
int jbig2_image_write_pbm_file(Jbig2Image *image, char *filename);
int jbig2_image_write_pbm(Jbig2Image *image, FILE *out);
Jbig2Image *jbig2_image_read_pbm_file(Jbig2Ctx *ctx, char *filename);
Jbig2Image *jbig2_image_read_pbm(Jbig2Ctx *ctx, FILE *in);
 
#ifdef HAVE_LIBPNG
int jbig2_image_write_png_file(Jbig2Image *image, char *filename);
int jbig2_image_write_png(Jbig2Image *image, FILE *out);
#endif
 
#endif /* _JBIG2_IMAGE_H */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_image_pbm.c
0,0 → 1,150
/*
jbig2dec
 
Copyright (C) 2009 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stdio.h>
#include <ctype.h>
 
#include "jbig2.h"
#include "jbig2_image.h"
 
/* take an image structure and write it to a file in pbm format */
 
int jbig2_image_write_pbm_file(Jbig2Image *image, char *filename)
{
FILE *out;
int error;
 
if ((out = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "unable to open '%s' for writing", filename);
return 1;
}
 
error = jbig2_image_write_pbm(image, out);
 
fclose(out);
return (error);
}
 
/* write out an image struct as a pbm stream to an open file pointer */
 
int jbig2_image_write_pbm(Jbig2Image *image, FILE *out)
{
/* pbm header */
fprintf(out, "P4\n%d %d\n", image->width, image->height);
 
/* pbm format pads to a byte boundary, so we can
just write out the whole data buffer
NB: this assumes minimal stride for the width */
fwrite(image->data, 1, image->height*image->stride, out);
 
/* success */
return 0;
}
 
/* take an image from a file in pbm format */
Jbig2Image *jbig2_image_read_pbm_file(Jbig2Ctx *ctx, char *filename)
{
FILE *in;
Jbig2Image *image;
 
if ((in = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "unable to open '%s' for reading\n", filename);
return NULL;
}
 
image = jbig2_image_read_pbm(ctx, in);
 
fclose(in);
 
return (image);
}
 
/* FIXME: should handle multi-image files */
Jbig2Image *jbig2_image_read_pbm(Jbig2Ctx *ctx, FILE *in)
{
int i, dim[2];
int done;
Jbig2Image *image;
int c;
char buf[32];
 
/* look for 'P4' magic */
while ((c = fgetc(in)) != 'P') {
if (feof(in)) return NULL;
}
if ((c = fgetc(in)) != '4') {
fprintf(stderr, "not a binary pbm file.\n");
return NULL;
}
/* read size. we must find two decimal numbers representing
the image dimensions. 'done' will index whether we're
looking for the width or the height and 'i' will be our
array index for copying strings into our buffer */
done = 0;
i = 0;
while (done < 2) {
c = fgetc(in);
/* skip whitespace */
if (c == ' ' || c == '\t' || c == '\r' || c == '\n') continue;
/* skip comments */
if (c == '#') {
while ((c = fgetc(in)) != '\n');
continue;
}
/* report unexpected eof */
if (c == EOF) {
fprintf(stderr, "end-of-file parsing pbm header\n");
return NULL;
}
if (isdigit(c)) {
buf[i++] = c;
while (isdigit(c = fgetc(in))) {
if (i >= 32) {
fprintf(stderr, "pbm parsing error\n");
return NULL;
}
buf[i++] = c;
}
buf[i] = '\0';
if (sscanf(buf, "%d", &dim[done]) != 1) {
fprintf(stderr, "couldn't read pbm image dimensions\n");
return NULL;
}
i = 0;
done++;
}
}
/* allocate image structure */
image = jbig2_image_new(ctx, dim[0], dim[1]);
if (image == NULL) {
fprintf(stderr, "could not allocate %dx%d image for pbm file\n", dim[0], dim[1]);
return NULL;
}
/* the pbm data is byte-aligned, so we can
do a simple block read */
fread(image->data, 1, image->height*image->stride, in);
if (feof(in)) {
fprintf(stderr, "unexpected end of pbm file.\n");
jbig2_image_release(ctx, image);
return NULL;
}
/* success */
return image;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_metadata.c
0,0 → 1,155
/*
jbig2dec
 
Copyright (C) 2003 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#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)
{
int i;
 
if (md->keys) {
/* assume we own the pointers */
for (i = 0; i < md->entries; i++)
jbig2_free(ctx->allocator, md->keys[i]);
jbig2_free(ctx->allocator, md->keys);
}
if (md->values) {
for (i = 0; i < md->entries; i++)
jbig2_free(ctx->allocator, md->values[i]);
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_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_comment_unicode(Jbig2Ctx *ctx, Jbig2Segment *segment,
const uint8_t *segment_data)
{
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled unicode comment segment");
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_metadata.h
0,0 → 1,48
/*
jbig2dec
 
Copyright (C) 2003 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
 
#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_comment_ascii(Jbig2Ctx *ctx, Jbig2Segment *segment,
const uint8_t *segment_data);
int jbig2_comment_unicode(Jbig2Ctx *ctx, Jbig2Segment *segment,
const uint8_t *segment_data);
 
#endif /* _JBIG2_METADATA_H */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_mmr.c
0,0 → 1,998
/*
jbig2dec
 
Copyright (C) 2001-2002 Artifex Software, Inc.
 
This software is provided AS-IS with no warranty,
either express or implied.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* An implementation of MMR decoding. This is based on the
implementation in Fitz, which in turn is based on the one
in Ghostscript.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h>
#include <stdio.h>
#include <string.h>
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_generic.h"
#include "jbig2_mmr.h"
 
typedef struct {
int width;
int height;
const byte *data;
size_t size;
int data_index;
int bit_index;
uint32_t word;
} Jbig2MmrCtx;
 
 
static void
jbig2_decode_mmr_init(Jbig2MmrCtx *mmr, int width, int height, const byte *data, size_t size)
{
int i;
uint32_t word = 0;
 
mmr->width = width;
mmr->height = height;
mmr->data = data;
mmr->size = size;
mmr->data_index = 0;
mmr->bit_index = 0;
 
for (i = 0; i < size && i < 4; i++)
word |= (data[i] << ((3 - i) << 3));
mmr->word = word;
}
 
static void
jbig2_decode_mmr_consume(Jbig2MmrCtx *mmr, int n_bits)
{
mmr->word <<= n_bits;
mmr->bit_index += n_bits;
while (mmr->bit_index >= 8) {
mmr->bit_index -= 8;
if (mmr->data_index + 4 < mmr->size)
mmr->word |= (mmr->data[mmr->data_index + 4] << mmr->bit_index);
mmr->data_index++;
}
}
 
/*
<raph> the first 2^(initialbits) entries map bit patterns to decodes
<raph> let's say initial_bits is 8 for the sake of example
<raph> and that the code is 1001
<raph> that means that entries 0x90 .. 0x9f have the entry { val, 4 }
<raph> because those are all the bytes that start with the code
<raph> and the 4 is the length of the code
... if (n_bits > initial_bits) ...
<raph> anyway, in that case, it basically points to a mini table
<raph> the n_bits is the maximum length of all codes beginning with that byte
<raph> so 2^(n_bits - initial_bits) is the size of the mini-table
<raph> peter came up with this, and it makes sense
*/
 
typedef struct {
short val;
short n_bits;
} mmr_table_node;
 
/* white decode table (runlength huffman codes) */
const mmr_table_node jbig2_mmr_white_decode[] = {
{ 256, 12 },
{ 272, 12 },
{ 29, 8 },
{ 30, 8 },
{ 45, 8 },
{ 46, 8 },
{ 22, 7 },
{ 22, 7 },
{ 23, 7 },
{ 23, 7 },
{ 47, 8 },
{ 48, 8 },
{ 13, 6 },
{ 13, 6 },
{ 13, 6 },
{ 13, 6 },
{ 20, 7 },
{ 20, 7 },
{ 33, 8 },
{ 34, 8 },
{ 35, 8 },
{ 36, 8 },
{ 37, 8 },
{ 38, 8 },
{ 19, 7 },
{ 19, 7 },
{ 31, 8 },
{ 32, 8 },
{ 1, 6 },
{ 1, 6 },
{ 1, 6 },
{ 1, 6 },
{ 12, 6 },
{ 12, 6 },
{ 12, 6 },
{ 12, 6 },
{ 53, 8 },
{ 54, 8 },
{ 26, 7 },
{ 26, 7 },
{ 39, 8 },
{ 40, 8 },
{ 41, 8 },
{ 42, 8 },
{ 43, 8 },
{ 44, 8 },
{ 21, 7 },
{ 21, 7 },
{ 28, 7 },
{ 28, 7 },
{ 61, 8 },
{ 62, 8 },
{ 63, 8 },
{ 0, 8 },
{ 320, 8 },
{ 384, 8 },
{ 10, 5 },
{ 10, 5 },
{ 10, 5 },
{ 10, 5 },
{ 10, 5 },
{ 10, 5 },
{ 10, 5 },
{ 10, 5 },
{ 11, 5 },
{ 11, 5 },
{ 11, 5 },
{ 11, 5 },
{ 11, 5 },
{ 11, 5 },
{ 11, 5 },
{ 11, 5 },
{ 27, 7 },
{ 27, 7 },
{ 59, 8 },
{ 60, 8 },
{ 288, 9 },
{ 290, 9 },
{ 18, 7 },
{ 18, 7 },
{ 24, 7 },
{ 24, 7 },
{ 49, 8 },
{ 50, 8 },
{ 51, 8 },
{ 52, 8 },
{ 25, 7 },
{ 25, 7 },
{ 55, 8 },
{ 56, 8 },
{ 57, 8 },
{ 58, 8 },
{ 192, 6 },
{ 192, 6 },
{ 192, 6 },
{ 192, 6 },
{ 1664, 6 },
{ 1664, 6 },
{ 1664, 6 },
{ 1664, 6 },
{ 448, 8 },
{ 512, 8 },
{ 292, 9 },
{ 640, 8 },
{ 576, 8 },
{ 294, 9 },
{ 296, 9 },
{ 298, 9 },
{ 300, 9 },
{ 302, 9 },
{ 256, 7 },
{ 256, 7 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 2, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 3, 4 },
{ 128, 5 },
{ 128, 5 },
{ 128, 5 },
{ 128, 5 },
{ 128, 5 },
{ 128, 5 },
{ 128, 5 },
{ 128, 5 },
{ 8, 5 },
{ 8, 5 },
{ 8, 5 },
{ 8, 5 },
{ 8, 5 },
{ 8, 5 },
{ 8, 5 },
{ 8, 5 },
{ 9, 5 },
{ 9, 5 },
{ 9, 5 },
{ 9, 5 },
{ 9, 5 },
{ 9, 5 },
{ 9, 5 },
{ 9, 5 },
{ 16, 6 },
{ 16, 6 },
{ 16, 6 },
{ 16, 6 },
{ 17, 6 },
{ 17, 6 },
{ 17, 6 },
{ 17, 6 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 4, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 14, 6 },
{ 14, 6 },
{ 14, 6 },
{ 14, 6 },
{ 15, 6 },
{ 15, 6 },
{ 15, 6 },
{ 15, 6 },
{ 64, 5 },
{ 64, 5 },
{ 64, 5 },
{ 64, 5 },
{ 64, 5 },
{ 64, 5 },
{ 64, 5 },
{ 64, 5 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ 7, 4 },
{ -2, 3 },
{ -2, 3 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -3, 4 },
{ 1792, 3 },
{ 1792, 3 },
{ 1984, 4 },
{ 2048, 4 },
{ 2112, 4 },
{ 2176, 4 },
{ 2240, 4 },
{ 2304, 4 },
{ 1856, 3 },
{ 1856, 3 },
{ 1920, 3 },
{ 1920, 3 },
{ 2368, 4 },
{ 2432, 4 },
{ 2496, 4 },
{ 2560, 4 },
{ 1472, 1 },
{ 1536, 1 },
{ 1600, 1 },
{ 1728, 1 },
{ 704, 1 },
{ 768, 1 },
{ 832, 1 },
{ 896, 1 },
{ 960, 1 },
{ 1024, 1 },
{ 1088, 1 },
{ 1152, 1 },
{ 1216, 1 },
{ 1280, 1 },
{ 1344, 1 },
{ 1408, 1 }
};
 
/* black decode table (runlength huffman codes) */
const mmr_table_node jbig2_mmr_black_decode[] = {
{ 128, 12 },
{ 160, 13 },
{ 224, 12 },
{ 256, 12 },
{ 10, 7 },
{ 11, 7 },
{ 288, 12 },
{ 12, 7 },
{ 9, 6 },
{ 9, 6 },
{ 8, 6 },
{ 8, 6 },
{ 7, 5 },
{ 7, 5 },
{ 7, 5 },
{ 7, 5 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 6, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 5, 4 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 1, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 4, 3 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 3, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ 2, 2 },
{ -2, 4 },
{ -2, 4 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -1, 0 },
{ -3, 5 },
{ 1792, 4 },
{ 1792, 4 },
{ 1984, 5 },
{ 2048, 5 },
{ 2112, 5 },
{ 2176, 5 },
{ 2240, 5 },
{ 2304, 5 },
{ 1856, 4 },
{ 1856, 4 },
{ 1920, 4 },
{ 1920, 4 },
{ 2368, 5 },
{ 2432, 5 },
{ 2496, 5 },
{ 2560, 5 },
{ 18, 3 },
{ 18, 3 },
{ 18, 3 },
{ 18, 3 },
{ 18, 3 },
{ 18, 3 },
{ 18, 3 },
{ 18, 3 },
{ 52, 5 },
{ 52, 5 },
{ 640, 6 },
{ 704, 6 },
{ 768, 6 },
{ 832, 6 },
{ 55, 5 },
{ 55, 5 },
{ 56, 5 },
{ 56, 5 },
{ 1280, 6 },
{ 1344, 6 },
{ 1408, 6 },
{ 1472, 6 },
{ 59, 5 },
{ 59, 5 },
{ 60, 5 },
{ 60, 5 },
{ 1536, 6 },
{ 1600, 6 },
{ 24, 4 },
{ 24, 4 },
{ 24, 4 },
{ 24, 4 },
{ 25, 4 },
{ 25, 4 },
{ 25, 4 },
{ 25, 4 },
{ 1664, 6 },
{ 1728, 6 },
{ 320, 5 },
{ 320, 5 },
{ 384, 5 },
{ 384, 5 },
{ 448, 5 },
{ 448, 5 },
{ 512, 6 },
{ 576, 6 },
{ 53, 5 },
{ 53, 5 },
{ 54, 5 },
{ 54, 5 },
{ 896, 6 },
{ 960, 6 },
{ 1024, 6 },
{ 1088, 6 },
{ 1152, 6 },
{ 1216, 6 },
{ 64, 3 },
{ 64, 3 },
{ 64, 3 },
{ 64, 3 },
{ 64, 3 },
{ 64, 3 },
{ 64, 3 },
{ 64, 3 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 13, 1 },
{ 23, 4 },
{ 23, 4 },
{ 50, 5 },
{ 51, 5 },
{ 44, 5 },
{ 45, 5 },
{ 46, 5 },
{ 47, 5 },
{ 57, 5 },
{ 58, 5 },
{ 61, 5 },
{ 256, 5 },
{ 16, 3 },
{ 16, 3 },
{ 16, 3 },
{ 16, 3 },
{ 17, 3 },
{ 17, 3 },
{ 17, 3 },
{ 17, 3 },
{ 48, 5 },
{ 49, 5 },
{ 62, 5 },
{ 63, 5 },
{ 30, 5 },
{ 31, 5 },
{ 32, 5 },
{ 33, 5 },
{ 40, 5 },
{ 41, 5 },
{ 22, 4 },
{ 22, 4 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 14, 1 },
{ 15, 2 },
{ 15, 2 },
{ 15, 2 },
{ 15, 2 },
{ 15, 2 },
{ 15, 2 },
{ 15, 2 },
{ 15, 2 },
{ 128, 5 },
{ 192, 5 },
{ 26, 5 },
{ 27, 5 },
{ 28, 5 },
{ 29, 5 },
{ 19, 4 },
{ 19, 4 },
{ 20, 4 },
{ 20, 4 },
{ 34, 5 },
{ 35, 5 },
{ 36, 5 },
{ 37, 5 },
{ 38, 5 },
{ 39, 5 },
{ 21, 4 },
{ 21, 4 },
{ 42, 5 },
{ 43, 5 },
{ 0, 3 },
{ 0, 3 },
{ 0, 3 },
{ 0, 3 }
};
 
#define getbit(buf, x) ( ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 )
 
static int
jbig2_find_changing_element(const byte *line, int x, int w)
{
int a, b;
 
if (line == 0)
return w;
 
if (x == -1) {
a = 0;
x = 0;
}
else {
a = getbit(line, x);
x ++;
}
 
while (x < w) {
b = getbit(line, x);
if (a != b)
break;
x++;
}
 
return x;
}
 
static int
jbig2_find_changing_element_of_color(const byte *line, int x, int w, int color)
{
if (line == 0)
return w;
x = jbig2_find_changing_element(line, x, w);
if (x < w && getbit(line, x) != color)
x = jbig2_find_changing_element(line, x, w);
return x;
}
 
static const byte lm[8] = { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };
static const byte rm[8] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
 
static void
jbig2_set_bits(byte *line, int x0, int x1)
{
int a0, a1, b0, b1, a;
 
a0 = x0 >> 3;
a1 = x1 >> 3;
 
b0 = x0 & 7;
b1 = x1 & 7;
 
if (a0 == a1) {
line[a0] |= lm[b0] & rm[b1];
}
else {
line[a0] |= lm[b0];
for (a = a0 + 1; a < a1; a++)
line[a] = 0xFF;
line[a1] |= rm[b1];
}
}
 
 
static int
jbig2_decode_get_code(Jbig2MmrCtx *mmr, const mmr_table_node *table, int initial_bits)
{
uint32_t word = mmr->word;
int table_ix = word >> (32 - initial_bits);
int val = table[table_ix].val;
int n_bits = table[table_ix].n_bits;
 
if (n_bits > initial_bits) {
int mask = (1 << (32 - initial_bits)) - 1;
table_ix = val + ((word & mask) >> (32 - n_bits));
val = table[table_ix].val;
n_bits = initial_bits + table[table_ix].n_bits;
}
 
jbig2_decode_mmr_consume(mmr, n_bits);
 
return val;
}
 
static int
jbig2_decode_get_run(Jbig2MmrCtx *mmr, const mmr_table_node *table, int initial_bits)
{
int result = 0;
int val;
 
do {
val = jbig2_decode_get_code(mmr, table, initial_bits);
result += val;
} while (val >= 64);
 
return result;
}
 
static void
jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst)
{
int a0, a1, a2, b1, b2;
int c;
 
a0 = -1;
c = 0; /* 0 is white, black is 1 */
 
while (1)
{
uint32_t word = mmr->word;
/* printf ("%08x\n", word); */
 
if (a0 >= mmr->width)
break;
 
if ((word >> (32 - 3)) == 1)
{
int white_run, black_run;
 
jbig2_decode_mmr_consume(mmr, 3);
 
if (a0 == -1)
a0 = 0;
 
if (c == 0) {
white_run = jbig2_decode_get_run(mmr, jbig2_mmr_white_decode, 8);
black_run = jbig2_decode_get_run(mmr, jbig2_mmr_black_decode, 7);
a1 = a0 + white_run;
a2 = a1 + black_run;
if (a1 > mmr->width) a1 = mmr->width;
if (a2 > mmr->width) a2 = mmr->width;
jbig2_set_bits(dst, a1, a2);
a0 = a2;
/* printf ("H %d %d\n", white_run, black_run); */
}
else
{
black_run = jbig2_decode_get_run(mmr, jbig2_mmr_black_decode, 7);
white_run = jbig2_decode_get_run(mmr, jbig2_mmr_white_decode, 8);
a1 = a0 + black_run;
a2 = a1 + white_run;
if (a1 > mmr->width) a1 = mmr->width;
if (a2 > mmr->width) a2 = mmr->width;
jbig2_set_bits(dst, a0, a1);
a0 = a2;
/* printf ("H %d %d\n", black_run, white_run); */
}
}
 
else if ((word >> (32 - 4)) == 1)
{
/* printf ("P\n"); */
jbig2_decode_mmr_consume(mmr, 4);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
b2 = jbig2_find_changing_element(ref, b1, mmr->width);
if (c) jbig2_set_bits(dst, a0, b2);
a0 = b2;
}
 
else if ((word >> (32 - 1)) == 1)
{
/* printf ("V(0)\n"); */
jbig2_decode_mmr_consume(mmr, 1);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
if (c) jbig2_set_bits(dst, a0, b1);
a0 = b1;
c = !c;
}
 
else if ((word >> (32 - 3)) == 3)
{
/* printf ("VR(1)\n"); */
jbig2_decode_mmr_consume(mmr, 3);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
if (b1 + 1 > mmr->width) break;
if (c) jbig2_set_bits(dst, a0, b1 + 1);
a0 = b1 + 1;
c = !c;
}
 
else if ((word >> (32 - 6)) == 3)
{
/* printf ("VR(2)\n"); */
jbig2_decode_mmr_consume(mmr, 6);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
if (b1 + 2 > mmr->width) break;
if (c) jbig2_set_bits(dst, a0, b1 + 2);
a0 = b1 + 2;
c = !c;
}
 
else if ((word >> (32 - 7)) == 3)
{
/* printf ("VR(3)\n"); */
jbig2_decode_mmr_consume(mmr, 7);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
if (b1 + 3 > mmr->width) break;
if (c) jbig2_set_bits(dst, a0, b1 + 3);
a0 = b1 + 3;
c = !c;
}
 
else if ((word >> (32 - 3)) == 2)
{
/* printf ("VL(1)\n"); */
jbig2_decode_mmr_consume(mmr, 3);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
if (b1 - 1 < 0) break;
if (c) jbig2_set_bits(dst, a0, b1 - 1);
a0 = b1 - 1;
c = !c;
}
 
else if ((word >> (32 - 6)) == 2)
{
/* printf ("VL(2)\n"); */
jbig2_decode_mmr_consume(mmr, 6);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
if (b1 - 2 < 0) break;
if (c) jbig2_set_bits(dst, a0, b1 - 2);
a0 = b1 - 2;
c = !c;
}
 
else if ((word >> (32 - 7)) == 2)
{
/* printf ("VL(3)\n"); */
jbig2_decode_mmr_consume(mmr, 7);
b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
if (b1 - 3 < 0) break;
if (c) jbig2_set_bits(dst, a0, b1 - 3);
a0 = b1 - 3;
c = !c;
}
 
else
break;
}
}
 
int
jbig2_decode_generic_mmr(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
const byte *data, size_t size,
Jbig2Image *image)
{
Jbig2MmrCtx mmr;
const int rowstride = image->stride;
byte *dst = image->data;
byte *ref = NULL;
int y;
 
jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
 
for (y = 0; y < image->height; y++) {
memset(dst, 0, rowstride);
jbig2_decode_mmr_line(&mmr, ref, dst);
ref = dst;
dst += rowstride;
}
 
return 0;
}
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_mmr.h
0,0 → 1,22
/*
jbig2dec
 
Copyright (C) 2001 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
int
jbig2_decode_generic_mmr(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2GenericRegionParams *params,
const byte *data, size_t size,
Jbig2Image *image);
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_page.c
0,0 → 1,327
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stdlib.h>
 
#include "jbig2.h"
#include "jbig2_priv.h"
 
#ifdef OUTPUT_PBM
#include <stdio.h>
#include "jbig2_image.h"
#endif
 
/* dump the page struct info */
static void
dump_page_info(Jbig2Ctx *ctx, Jbig2Segment *segment, Jbig2Page *page)
{
if (page->x_resolution == 0) {
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"page %d image is %dx%d (unknown res)", page->number,
page->width, page->height);
} else if (page->x_resolution == page->y_resolution) {
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"page %d image is %dx%d (%d ppm)", page->number,
page->width, page->height,
page->x_resolution);
} else {
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"page %d image is %dx%d (%dx%d ppm)", page->number,
page->width, page->height,
page->x_resolution, page->y_resolution);
}
if (page->striped) {
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"\tmaximum stripe size: %d", page->stripe_size);
}
}
 
/**
* jbig2_page_info: parse page info segment
*
* Parse the page info segment data and fill out a corresponding
* Jbig2Page struct and ready it for subsequent rendered data,
* including allocating an image buffer for the page (or the first stripe)
**/
int
jbig2_page_info (Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data)
{
Jbig2Page *page;
 
/* a new page info segment implies the previous page is finished */
page = &(ctx->pages[ctx->current_page]);
if ((page->number != 0) &&
((page->state == JBIG2_PAGE_NEW) || (page->state == JBIG2_PAGE_FREE))) {
page->state = JBIG2_PAGE_COMPLETE;
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unexpected page info segment, marking previous page finished");
}
 
/* find a free page */
{
int index, j;
index = ctx->current_page;
while (ctx->pages[index].state != JBIG2_PAGE_FREE) {
index++;
if (index >= ctx->max_page_index) {
/* grow the list */
ctx->pages = jbig2_realloc(ctx->allocator, ctx->pages,
(ctx->max_page_index <<= 2) * sizeof(Jbig2Page));
for (j=index; j < ctx->max_page_index; j++) {
ctx->pages[j].state = JBIG2_PAGE_FREE;
ctx->pages[j].number = 0;
ctx->pages[j].image = NULL;
 
}
}
}
page = &(ctx->pages[index]);
ctx->current_page = index;
page->state = JBIG2_PAGE_NEW;
page->number = segment->page_association;
}
 
/* FIXME: would be nice if we tried to work around this */
if (segment->data_length < 19) {
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"segment too short");
}
 
/* 7.4.8.x */
page->width = jbig2_get_int32(segment_data);
page->height = jbig2_get_int32(segment_data + 4);
 
page->x_resolution = jbig2_get_int32(segment_data + 8);
page->y_resolution = jbig2_get_int32(segment_data + 12);
page->flags = segment_data[16];
 
/* 7.4.8.6 */
{
int16_t striping = jbig2_get_int16(segment_data +17);
if (striping & 0x8000) {
page->striped = TRUE;
page->stripe_size = striping & 0x7FFF;
} else {
page->striped = FALSE;
page->stripe_size = 0; /* would page->height be better? */
}
}
if (page->height == 0xFFFFFFFF && page->striped == FALSE) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"height is unspecified but page is not markes as striped");
page->striped = TRUE;
}
page->end_row = 0;
 
if (segment->data_length > 19) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"extra data in segment");
}
 
dump_page_info(ctx, segment, page);
 
/* allocate an approprate page image buffer */
/* 7.4.8.2 */
if (page->height == 0xFFFFFFFF) {
page->image = jbig2_image_new(ctx, page->width, page->stripe_size);
} else {
page->image = jbig2_image_new(ctx, page->width, page->height);
}
if (page->image == NULL) {
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"failed to allocate buffer for page image");
} else {
/* 8.2 (3) fill the page with the default pixel value */
jbig2_image_clear(ctx, page->image, (page->flags & 4));
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"allocated %dx%d page image (%d bytes)",
page->image->width, page->image->height,
page->image->stride*page->image->height);
}
 
return 0;
}
 
/**
* jbig2_end_of_stripe: parse and implement an end of stripe segment
**/
int
jbig2_end_of_stripe(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data)
{
Jbig2Page page = ctx->pages[ctx->current_page];
int end_row;
 
end_row = jbig2_get_int32(segment_data);
if (end_row < page.end_row) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"end of stripe segment with non-positive end row advance"
" (new end row %d vs current end row %d)",
end_row, page.end_row);
} else {
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"end of stripe: advancing end row to %d", end_row);
}
 
page.end_row = end_row;
 
return 0;
}
 
/**
* jbig2_complete_page: complete a page image
*
* called upon seeing an 'end of page' segment, this routine
* marks a page as completed so it can be returned.
* compositing will have already happened in the previous
* segment handlers.
**/
int
jbig2_complete_page (Jbig2Ctx *ctx)
{
 
/* check for unfinished segments */
if (ctx->segment_index != ctx->n_segments) {
Jbig2Segment *segment = ctx->segments[ctx->segment_index];
int code = 0;
/* Some versions of Xerox Workcentre generate PDF files
with the segment data length field of the last segment
set to -1. Try to cope with this here. */
if ((segment->data_length & 0xffffffff) == 0xffffffff) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"File has an invalid segment data length!"
" Trying to decode using the available data.");
segment->data_length = ctx->buf_wr_ix - ctx->buf_rd_ix;
code = jbig2_parse_segment(ctx, segment, ctx->buf + ctx->buf_rd_ix);
ctx->buf_rd_ix += segment->data_length;
ctx->segment_index++;
}
}
ctx->pages[ctx->current_page].state = JBIG2_PAGE_COMPLETE;
 
return 0;
}
 
/**
* jbig2_end_of_page: parse and implement an end of page segment
**/
int
jbig2_end_of_page(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data)
{
uint32_t page_number = ctx->pages[ctx->current_page].number;
 
if (segment->page_association != page_number) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"end of page marker for page %d doesn't match current page number %d",
segment->page_association, page_number);
}
 
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"end of page %d", page_number);
 
jbig2_complete_page(ctx);
 
#ifdef OUTPUT_PBM
jbig2_image_write_pbm(ctx->pages[ctx->current_page].image, stdout);
#endif
 
return 0;
}
 
/**
* jbig2_add_page_result: composite a decoding result onto a page
*
* this is called to add the results of segment decode (when it
* is an image) to a page image buffer
**/
int
jbig2_page_add_result(Jbig2Ctx *ctx, Jbig2Page *page, Jbig2Image *image,
int x, int y, Jbig2ComposeOp op)
{
/* grow the page to accomodate a new stripe if necessary */
if (page->striped) {
int new_height = y + image->height + page->end_row;
if (page->image->height < new_height) {
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
"growing page buffer to %d rows "
"to accomodate new stripe", new_height);
jbig2_image_resize(ctx, page->image,
page->image->width, new_height);
}
}
 
jbig2_image_compose(ctx, page->image, image,
x, y + page->end_row, JBIG2_COMPOSE_OR);
 
return 0;
}
 
/**
* jbig2_get_page: return the next available page image buffer
*
* the client can call this at any time to check if any pages
* have been decoded. If so, it returns the first available
* one. The client should then call jbig2_release_page() when
* it no longer needs to refer to the image buffer.
*
* since this is a public routine for the library clients, we
* return an image structure pointer, even though the function
* name refers to a page; the page structure is private.
**/
Jbig2Image *jbig2_page_out(Jbig2Ctx *ctx)
{
int index;
 
/* search for a completed page */
for (index=0; index < ctx->max_page_index; index++) {
if (ctx->pages[index].state == JBIG2_PAGE_COMPLETE) {
ctx->pages[index].state = JBIG2_PAGE_RETURNED;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
"page %d returned to the client", ctx->pages[index].number);
return jbig2_image_clone(ctx, ctx->pages[index].image);
}
}
 
/* no pages available */
return NULL;
}
 
/**
* jbig2_release_page: tell the library a page can be freed
**/
int jbig2_release_page(Jbig2Ctx *ctx, Jbig2Image *image)
{
int index;
 
/* find the matching page struct and mark it released */
for (index = 0; index < ctx->max_page_index; index++) {
if (ctx->pages[index].image == image) {
jbig2_image_release(ctx, image);
ctx->pages[index].state = JBIG2_PAGE_RELEASED;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
"page %d released by the client", ctx->pages[index].number);
return 0;
}
}
 
/* no matching pages */
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
"jbig2_release_page called on unknown page");
return 1;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_priv.h
0,0 → 1,177
/*
jbig2dec
 
Copyright (C) 2002 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* library internals */
 
typedef uint8_t byte;
typedef int bool;
 
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
 
#ifndef NULL
#define NULL ((void*)0)
#endif
 
typedef enum {
JBIG2_FILE_HEADER,
JBIG2_FILE_SEQUENTIAL_HEADER,
JBIG2_FILE_SEQUENTIAL_BODY,
JBIG2_FILE_RANDOM_HEADERS,
JBIG2_FILE_RANDOM_BODIES,
JBIG2_FILE_EOF
} Jbig2FileState;
 
struct _Jbig2Ctx {
Jbig2Allocator *allocator;
Jbig2Options options;
const Jbig2Ctx *global_ctx;
Jbig2ErrorCallback error_callback;
void *error_callback_data;
 
byte *buf;
size_t buf_size;
unsigned int buf_rd_ix;
unsigned int buf_wr_ix;
 
Jbig2FileState state;
 
uint8_t file_header_flags;
int32_t n_pages;
 
int n_segments_max;
Jbig2Segment **segments;
int n_segments; /* index of last segment header parsed */
int segment_index; /* index of last segment body parsed */
 
/* list of decoded pages, including the one in progress,
currently stored as a contiguous, 0-indexed array. */
int current_page;
int max_page_index;
Jbig2Page *pages;
};
 
int32_t
jbig2_get_int32 (const byte *buf);
 
int16_t
jbig2_get_int16 (const byte *buf);
 
/* dynamic memory management */
void *
jbig2_alloc (Jbig2Allocator *allocator, size_t size);
 
void
jbig2_free (Jbig2Allocator *allocator, void *p);
 
void *
jbig2_realloc (Jbig2Allocator *allocator, void *p, size_t size);
 
#define jbig2_new(ctx, t, size) ((t *)jbig2_alloc(ctx->allocator, (size) * sizeof(t)))
 
#define jbig2_renew(ctx, p, t, size) ((t *)jbig2_realloc(ctx->allocator, (p), (size) * sizeof(t)))
 
int
jbig2_error (Jbig2Ctx *ctx, Jbig2Severity severity, int32_t seg_idx,
const char *fmt, ...);
 
/* the page structure handles decoded page
results. it's allocated by a 'page info'
segement and marked complete by an 'end of page'
segment.
*/
typedef enum {
JBIG2_PAGE_FREE,
JBIG2_PAGE_NEW,
JBIG2_PAGE_COMPLETE,
JBIG2_PAGE_RETURNED,
JBIG2_PAGE_RELEASED
} Jbig2PageState;
 
struct _Jbig2Page {
Jbig2PageState state;
uint32_t number;
uint32_t height, width; /* in pixels */
uint32_t x_resolution,
y_resolution; /* in pixels per meter */
uint16_t stripe_size;
bool striped;
int end_row;
uint8_t flags;
Jbig2Image *image;
};
 
int jbig2_page_info (Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data);
int jbig2_end_of_stripe(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data);
int jbig2_end_of_page(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data);
int jbig2_extension_segment(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data);
 
typedef enum {
JBIG2_COMPOSE_OR = 0,
JBIG2_COMPOSE_AND = 1,
JBIG2_COMPOSE_XOR = 2,
JBIG2_COMPOSE_XNOR = 3,
JBIG2_COMPOSE_REPLACE = 4
} Jbig2ComposeOp;
 
int jbig2_image_compose(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src, int x, int y, Jbig2ComposeOp op);
int jbig2_page_add_result(Jbig2Ctx *ctx, Jbig2Page *page, Jbig2Image *src, int x, int y, Jbig2ComposeOp op);
 
/* region segment info */
 
typedef struct {
int32_t width;
int32_t height;
int32_t x;
int32_t y;
Jbig2ComposeOp op;
uint8_t flags;
} Jbig2RegionSegmentInfo;
 
void jbig2_get_region_segment_info(Jbig2RegionSegmentInfo *info, const uint8_t *segment_data);
int jbig2_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data);
 
/* 7.4 */
int jbig2_immediate_generic_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const uint8_t *segment_data);
int jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data);
 
int jbig2_pattern_dictionary(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data);
int jbig2_halftone_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data);
 
 
/* The word stream design is a compromise between simplicity and
trying to amortize the number of method calls. Each ::get_next_word
invocation pulls 4 bytes from the stream, packed big-endian into a
32 bit word. The offset argument is provided as a convenience. It
begins at 0 and increments by 4 for each successive invocation. */
typedef struct _Jbig2WordStream Jbig2WordStream;
 
struct _Jbig2WordStream {
uint32_t (*get_next_word) (Jbig2WordStream *self, int offset);
};
 
Jbig2WordStream *
jbig2_word_stream_buf_new(Jbig2Ctx *ctx, const byte *data, size_t size);
 
void
jbig2_word_stream_buf_free(Jbig2Ctx *ctx, Jbig2WordStream *ws);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_refinement.c
0,0 → 1,440
/*
jbig2dec
 
Copyright (C) 2004 Artifex Software, Inc.
 
This software is provided AS-IS with no warranty,
either express or implied.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/**
* Generic Refinement region handlers.
**/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h>
#include <string.h> /* memcpy(), memset() */
 
#include <stdio.h>
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_generic.h"
#include "jbig2_image.h"
 
static int
jbig2_decode_refinement_template0(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2RefinementRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GR_stats)
{
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"refinement region template 0 NYI");
}
 
static int
jbig2_decode_refinement_template0_unopt(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2RefinementRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GR_stats)
{
const int GRW = image->width;
const int GRH = image->height;
const int dx = params->DX;
const int dy = params->DY;
Jbig2Image *ref = params->reference;
uint32_t CONTEXT;
int x,y;
bool bit;
 
for (y = 0; y < GRH; y++) {
for (x = 0; x < GRW; x++) {
CONTEXT = 0;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y + 0) << 0;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x + params->grat[0],
y + params->grat[1]) << 3;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+1, y-dy+1) << 4;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+0, y-dy+1) << 5;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx-1, y-dy+1) << 6;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+1, y-dy+0) << 7;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+0, y-dy+0) << 8;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx-1, y-dy+0) << 9;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+1, y-dy-1) << 10;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+0, y-dy-1) << 11;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+params->grat[2],
y-dy+params->grat[3]) << 12;
bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
}
#ifdef JBIG2_DEBUG_DUMP
{
static count = 0;
char name[32];
snprintf(name, 32, "refin-%d.pbm", count);
jbig2_image_write_pbm_file(ref, name);
snprintf(name, 32, "refout-%d.pbm", count);
jbig2_image_write_pbm_file(image, name);
count++;
}
#endif
 
return 0;
}
 
 
static int
jbig2_decode_refinement_template1_unopt(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2RefinementRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GR_stats)
{
const int GRW = image->width;
const int GRH = image->height;
const int dx = params->DX;
const int dy = params->DY;
Jbig2Image *ref = params->reference;
uint32_t CONTEXT;
int x,y;
bool bit;
 
for (y = 0; y < GRH; y++) {
for (x = 0; x < GRW; x++) {
CONTEXT = 0;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y + 0) << 0;
CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 1;
CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 2;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 3;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+1, y-dy+1) << 4;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+0, y-dy+1) << 5;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+1, y-dy+0) << 6;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+0, y-dy+0) << 7;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx-1, y-dy+0) << 8;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+0, y-dy-1) << 9;
bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]);
jbig2_image_set_pixel(image, x, y, bit);
}
}
 
#ifdef JBIG2_DEBUG_DUMP
{
static count = 0;
char name[32];
snprintf(name, 32, "refin-%d.pbm", count);
jbig2_image_write_pbm_file(ref, name);
snprintf(name, 32, "refout-%d.pbm", count);
jbig2_image_write_pbm_file(image, name);
count++;
}
#endif
 
return 0;
}
 
static int
jbig2_decode_refinement_template1(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2RefinementRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GR_stats)
{
const int GRW = image->width;
const int GRH = image->height;
const int stride = image->stride;
const int refstride = params->reference->stride;
const int dy = params->DY;
byte *grreg_line = (byte *)image->data;
byte *grref_line = (byte *)params->reference->data;
int x,y;
 
for (y = 0; y < GRH; y++) {
const int padded_width = (GRW + 7) & -8;
uint32_t CONTEXT;
uint32_t refline_m1; /* previous line of the reference bitmap */
uint32_t refline_0; /* current line of the reference bitmap */
uint32_t refline_1; /* next line of the reference bitmap */
uint32_t line_m1; /* previous line of the decoded bitmap */
 
line_m1 = (y >= 1) ? grreg_line[-stride] : 0;
refline_m1 = ((y-dy) >= 1) ? grref_line[(-1-dy)*stride] << 2: 0;
refline_0 = (((y-dy) > 0) && ((y-dy) < GRH)) ? grref_line[(0-dy)*stride] << 4 : 0;
refline_1 = (y < GRH - 1) ? grref_line[(+1-dy)*stride] << 7 : 0;
CONTEXT = ((line_m1 >> 5) & 0x00e) |
((refline_1 >> 5) & 0x030) |
((refline_0 >> 5) & 0x1c0) |
((refline_m1 >> 5) & 0x200);
 
for (x = 0; x < padded_width; x += 8) {
byte result = 0;
int x_minor;
const int minor_width = GRW - x > 8 ? 8 : GRW - x;
 
if (y >= 1) {
line_m1 = (line_m1 << 8) |
(x + 8 < GRW ? grreg_line[-stride + (x >> 3) + 1] : 0);
refline_m1 = (refline_m1 << 8) |
(x + 8 < GRW ? grref_line[-refstride + (x >> 3) + 1] << 2 : 0);
}
 
refline_0 = (refline_0 << 8) |
(x + 8 < GRW ? grref_line[(x >> 3) + 1] << 4 : 0);
 
if (y < GRH - 1)
refline_1 = (refline_1 << 8) |
(x + 8 < GRW ? grref_line[+refstride + (x >> 3) + 1] << 7 : 0);
else
refline_1 = 0;
 
/* this is the speed critical inner-loop */
for (x_minor = 0; x_minor < minor_width; x_minor++) {
bool bit;
 
bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]);
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x0d6) << 1) | bit |
((line_m1 >> (9 - x_minor)) & 0x002) |
((refline_1 >> (9 - x_minor)) & 0x010) |
((refline_0 >> (9 - x_minor)) & 0x040) |
((refline_m1 >> (9 - x_minor)) & 0x200);
}
 
grreg_line[x>>3] = result;
 
}
 
grreg_line += stride;
grref_line += refstride;
 
}
 
return 0;
 
}
 
 
/**
* jbig2_decode_refinement_region: Decode a generic refinement region.
* @ctx: The context for allocation and error reporting.
* @segment: A segment reference for error reporting.
* @params: Decoding parameter set.
* @as: Arithmetic decoder state.
* @image: Where to store the decoded image.
* @GR_stats: Arithmetic stats.
*
* Decodes a generic refinement region, according to section 6.3.
* an already allocated Jbig2Image object in @image for the result.
*
* Because this API is based on an arithmetic decoding state, it is
* not suitable for MMR decoding.
*
* Return code: 0 on success.
**/
int
jbig2_decode_refinement_region(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2RefinementRegionParams *params,
Jbig2ArithState *as,
Jbig2Image *image,
Jbig2ArithCx *GR_stats)
{
{
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"decoding generic refinement region with offset %d,%x,\n"
" GRTEMPLATE=%d, TPGRON=%d, RA1=(%d,%d) RA2=(%d,%d)\n",
params->DX, params->DY, params->GRTEMPLATE, params->TPGRON,
params->grat[0], params->grat[1], params->grat[2], params->grat[3]);
}
if (params->TPGRON)
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"decode_refinement_region: typical prediction coding NYI");
if (params->GRTEMPLATE)
return jbig2_decode_refinement_template1_unopt(ctx, segment, params,
as, image, GR_stats);
else
return jbig2_decode_refinement_template0_unopt(ctx, segment, params,
as, image, GR_stats);
}
 
/**
* Find the first referred-to intermediate region segment
* with a non-NULL result for use as a reference image
*/
Jbig2Segment *
jbig2_region_find_referred(Jbig2Ctx *ctx,Jbig2Segment *segment)
{
const int nsegments = segment->referred_to_segment_count;
Jbig2Segment *rsegment;
int index;
 
for (index = 0; index < nsegments; index++) {
rsegment = jbig2_find_segment(ctx,
segment->referred_to_segments[index]);
if (rsegment == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"could not find referred to segment %d",
segment->referred_to_segments[index]);
continue;
}
switch (rsegment->flags & 63) {
case 4: /* intermediate text region */
case 20: /* intermediate halftone region */
case 36: /* intermediate generic region */
case 40: /* intermediate generic refinement region */
if (rsegment->result) return rsegment;
break;
default: /* keep looking */
break;
}
}
/* no appropriate reference was found. */
return NULL;
}
 
/**
* Handler for generic refinement region segments
*/
int
jbig2_refinement_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data)
{
Jbig2RefinementRegionParams params;
Jbig2RegionSegmentInfo rsi;
int offset = 0;
byte seg_flags;
 
/* 7.4.7 */
if (segment->data_length < 18)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
 
jbig2_get_region_segment_info(&rsi, segment_data);
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"generic region: %d x %d @ (%d, %d), flags = %02x",
rsi.width, rsi.height, rsi.x, rsi.y, rsi.flags);
 
/* 7.4.7.2 */
seg_flags = segment_data[17];
params.GRTEMPLATE = seg_flags & 0x01;
params.TPGRON = seg_flags & 0x02 ? 1 : 0;
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"segment flags = %02x %s%s", seg_flags,
params.GRTEMPLATE ? " GRTEMPLATE" :"",
params.TPGRON ? " TPGRON" : "" );
if (seg_flags & 0xFC)
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"reserved segment flag bits are non-zero");
offset += 18;
 
/* 7.4.7.3 */
if (!params.GRTEMPLATE) {
if (segment->data_length < 22)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
params.grat[0] = segment_data[offset + 0];
params.grat[1] = segment_data[offset + 1];
params.grat[2] = segment_data[offset + 2];
params.grat[3] = segment_data[offset + 3];
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"grat1: (%d, %d) grat2: (%d, %d)",
params.grat[0], params.grat[1],
params.grat[2], params.grat[3]);
offset += 4;
}
 
/* 7.4.7.4 - set up the reference image */
if (segment->referred_to_segment_count) {
Jbig2Segment *ref;
 
ref = jbig2_region_find_referred(ctx, segment);
if (ref == NULL)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"could not find reference bitmap!");
/* the reference bitmap is the result of a previous
intermediate region segment; the reference selection
rules say to use the first one available, and not to
reuse any intermediate result, so we simply clone it
and free the original to keep track of this. */
params.reference = jbig2_image_clone(ctx, ref->result);
jbig2_image_release(ctx, ref->result);
ref->result = NULL;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"found reference bitmap in segment %d", ref->number);
} else {
/* the reference is just (a subset of) the page buffer */
params.reference = jbig2_image_clone(ctx,
ctx->pages[ctx->current_page].image);
/* TODO: subset the image if appropriate */
}
 
/* 7.4.7.5 */
params.DX = 0;
params.DY = 0;
{
Jbig2WordStream *ws;
Jbig2ArithState *as;
Jbig2ArithCx *GR_stats = NULL;
int stats_size;
Jbig2Image *image;
int code;
 
image = jbig2_image_new(ctx, rsi.width, rsi.height);
if (image == NULL)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"unable to allocate refinement image");
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"allocated %d x %d image buffer for region decode results",
rsi.width, rsi.height);
 
stats_size = params.GRTEMPLATE ? 1 << 10 : 1 << 13;
GR_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GR_stats, 0, stats_size);
 
ws = jbig2_word_stream_buf_new(ctx, segment_data + offset,
segment->data_length - offset);
as = jbig2_arith_new(ctx, ws);
code = jbig2_decode_refinement_region(ctx, segment, &params,
as, image, GR_stats);
 
jbig2_free(ctx->allocator, as);
jbig2_word_stream_buf_free(ctx, ws);
jbig2_free(ctx->allocator, GR_stats);
 
if ((segment->flags & 63) == 40) {
/* intermediate region. save the result for later */
segment->result = image;
} else {
/* immediate region. composite onto the page */
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"composing %dx%d decoded refinement region onto page at (%d, %d)",
rsi.width, rsi.height, rsi.x, rsi.y);
jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page],
image, rsi.x, rsi.y, rsi.op);
jbig2_image_release(ctx, image);
}
}
 
return 0;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_segment.c
0,0 → 1,295
/*
jbig2dec
 
Copyright (C) 2002-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h> /* size_t */
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_symbol_dict.h"
#include "jbig2_metadata.h"
 
Jbig2Segment *
jbig2_parse_segment_header (Jbig2Ctx *ctx, uint8_t *buf, size_t buf_size,
size_t *p_header_size)
{
Jbig2Segment *result;
uint8_t rtscarf;
uint32_t rtscarf_long;
uint32_t *referred_to_segments;
int referred_to_segment_count;
int referred_to_segment_size;
int pa_size;
int offset;
 
/* minimum possible size of a jbig2 segment header */
if (buf_size < 11)
return NULL;
 
result = (Jbig2Segment *)jbig2_alloc(ctx->allocator,
sizeof(Jbig2Segment));
 
/* 7.2.2 */
result->number = jbig2_get_int32(buf);
 
/* 7.2.3 */
result->flags = buf[4];
 
/* 7.2.4 referred-to segments */
rtscarf = buf[5];
if ((rtscarf & 0xe0) == 0xe0)
{
rtscarf_long = jbig2_get_int32(buf + 5);
referred_to_segment_count = rtscarf_long & 0x1fffffff;
offset = 5 + 4 + (referred_to_segment_count + 1) / 8;
}
else
{
referred_to_segment_count = (rtscarf >> 5);
offset = 5 + 1;
}
result->referred_to_segment_count = referred_to_segment_count;
 
/* we now have enough information to compute the full header length */
referred_to_segment_size = result->number <= 256 ? 1:
result->number <= 65536 ? 2 : 4; /* 7.2.5 */
pa_size = result->flags & 0x40 ? 4 : 1; /* 7.2.6 */
if (offset + referred_to_segment_count*referred_to_segment_size + pa_size + 4 > buf_size)
{
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, result->number,
"jbig2_parse_segment_header() called with insufficient data", -1);
jbig2_free (ctx->allocator, result);
return NULL;
}
 
/* 7.2.5 */
if (referred_to_segment_count)
{
int i;
 
referred_to_segments = jbig2_alloc(ctx->allocator, referred_to_segment_count * referred_to_segment_size * sizeof(uint32_t));
 
for (i = 0; i < referred_to_segment_count; i++) {
referred_to_segments[i] =
(referred_to_segment_size == 1) ? buf[offset] :
(referred_to_segment_size == 2) ? jbig2_get_int16(buf+offset) :
jbig2_get_int32(buf + offset);
offset += referred_to_segment_size;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, result->number,
"segment %d refers to segment %d",
result->number, referred_to_segments[i]);
}
result->referred_to_segments = referred_to_segments;
}
else /* no referred-to segments */
{
result->referred_to_segments = NULL;
}
 
/* 7.2.6 */
if (result->flags & 0x40) {
result->page_association = jbig2_get_int32(buf + offset);
offset += 4;
} else {
result->page_association = buf[offset++];
}
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, result->number,
"segment %d is associated with page %d",
result->number, result->page_association);
 
/* 7.2.7 */
result->data_length = jbig2_get_int32(buf + offset);
*p_header_size = offset + 4;
 
/* no body parsing results yet */
result->result = NULL;
 
return result;
}
 
void
jbig2_free_segment (Jbig2Ctx *ctx, Jbig2Segment *segment)
{
if (segment->referred_to_segments != NULL) {
jbig2_free(ctx->allocator, segment->referred_to_segments);
}
/* todo: we need either some separate fields or
a more complex result object rather than this
brittle special casing */
switch (segment->flags & 63) {
case 0: /* symbol dictionary */
if (segment->result != NULL)
jbig2_sd_release(ctx, segment->result);
break;
case 4: /* intermediate text region */
case 40: /* intermediate refinement region */
if (segment->result != NULL)
jbig2_image_release(ctx, segment->result);
break;
case 62:
if (segment->result != NULL)
jbig2_metadata_free(ctx, segment->result);
break;
default:
/* anything else is probably an undefined pointer */
break;
}
jbig2_free (ctx->allocator, segment);
}
 
/* find a segment by number */
Jbig2Segment *
jbig2_find_segment(Jbig2Ctx *ctx, uint32_t number)
{
int index, index_max = ctx->segment_index - 1;
const Jbig2Ctx *global_ctx = ctx->global_ctx;
 
/* FIXME: binary search would be better */
for (index = index_max; index >= 0; index--)
if (ctx->segments[index]->number == number)
return (ctx->segments[index]);
 
if (global_ctx)
for (index = global_ctx->segment_index - 1; index >= 0; index--)
if (global_ctx->segments[index]->number == number)
return (global_ctx->segments[index]);
 
/* didn't find a match */
return NULL;
}
 
/* parse the generic portion of a region segment data header */
void
jbig2_get_region_segment_info(Jbig2RegionSegmentInfo *info,
const uint8_t *segment_data)
{
/* 7.4.1 */
info->width = jbig2_get_int32(segment_data);
info->height = jbig2_get_int32(segment_data + 4);
info->x = jbig2_get_int32(segment_data + 8);
info->y = jbig2_get_int32(segment_data + 12);
info->flags = segment_data[16];
info->op = info->flags & 0x7;
}
 
/* dispatch code for extension segment parsing */
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_comment_ascii(ctx, segment, segment_data);
case 0x20000002: return jbig2_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;
}
 
/* general segment parsing dispatch */
int jbig2_parse_segment (Jbig2Ctx *ctx, Jbig2Segment *segment,
const uint8_t *segment_data)
{
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"Segment %d, flags=%x, type=%d, data_length=%d",
segment->number, segment->flags, segment->flags & 63,
segment->data_length);
switch (segment->flags & 63)
{
case 0:
return jbig2_symbol_dictionary(ctx, segment, segment_data);
case 4: /* intermediate text region */
case 6: /* immediate text region */
case 7: /* immediate lossless text region */
return jbig2_text_region(ctx, segment, segment_data);
#ifdef JBIG2_HALFTONE
case 16:
return jbig2_pattern_dictionary(ctx, segment, segment_data);
case 20: /* intermediate halftone region */
case 22: /* immediate halftone region */
case 23: /* immediate lossless halftone region */
return jbig2_halftone_region(ctx, segment, segment_data);
#else
case 16:
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled segment type 'pattern dictionary'");
case 20:
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled segment type 'intermediate halftone region'");
case 22:
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled segment type 'immediate halftone region'");
case 23:
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled segment type 'immediate lossless halftone region'");
#endif
case 36:
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled segment type 'intermediate generic region'");
case 38: /* immediate generic region */
case 39: /* immediate lossless generic region */
return jbig2_immediate_generic_region(ctx, segment, segment_data);
case 40: /* intermediate generic refinement region */
case 42: /* immediate generic refinement region */
case 43: /* immediate lossless generic refinement region */
return jbig2_refinement_region(ctx, segment, segment_data);
case 48:
return jbig2_page_info(ctx, segment, segment_data);
case 49:
return jbig2_end_of_page(ctx, segment, segment_data);
case 50:
return jbig2_end_of_stripe(ctx, segment, segment_data);
case 51:
ctx->state = JBIG2_FILE_EOF;
return jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"end of file");
case 52:
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled segment type 'profile'");
case 53:
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unhandled table segment");
case 62:
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);
}
return 0;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_symbol_dict.c
0,0 → 1,937
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* symbol dictionary segment decode and support */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h>
#include <string.h> /* memset() */
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_arith_int.h"
#include "jbig2_arith_iaid.h"
#include "jbig2_huffman.h"
#include "jbig2_generic.h"
#include "jbig2_mmr.h"
#include "jbig2_symbol_dict.h"
#include "jbig2_text.h"
 
#if defined(OUTPUT_PBM) || defined(DUMP_SYMDICT)
#include <stdio.h>
#include "jbig2_image.h"
#endif
 
/* Table 13 */
typedef struct {
bool SDHUFF;
bool SDREFAGG;
int32_t SDNUMINSYMS;
Jbig2SymbolDict *SDINSYMS;
uint32_t SDNUMNEWSYMS;
uint32_t SDNUMEXSYMS;
Jbig2HuffmanTable *SDHUFFDH;
Jbig2HuffmanTable *SDHUFFDW;
Jbig2HuffmanTable *SDHUFFBMSIZE;
Jbig2HuffmanTable *SDHUFFAGGINST;
int SDTEMPLATE;
int8_t sdat[8];
bool SDRTEMPLATE;
int8_t sdrat[4];
} Jbig2SymbolDictParams;
 
 
/* Utility routines */
 
#ifdef DUMP_SYMDICT
void
jbig2_dump_symbol_dict(Jbig2Ctx *ctx, Jbig2Segment *segment)
{
Jbig2SymbolDict *dict = (Jbig2SymbolDict *)segment->result;
int index;
char filename[24];
 
if (dict == NULL) return;
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"dumping symbol dict as %d individual png files\n", dict->n_symbols);
for (index = 0; index < dict->n_symbols; index++) {
snprintf(filename, sizeof(filename), "symbol_%02d-%04d.png",
segment->number, index);
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"dumping symbol %d/%d as '%s'", index, dict->n_symbols, filename);
#ifdef HAVE_LIBPNG
jbig2_image_write_png_file(dict->glyphs[index], filename);
#else
jbig2_image_write_pbm_file(dict->glyphs[index], filename);
#endif
}
}
#endif /* DUMP_SYMDICT */
 
/* return a new empty symbol dict */
Jbig2SymbolDict *
jbig2_sd_new(Jbig2Ctx *ctx, int n_symbols)
{
Jbig2SymbolDict *new = NULL;
 
new = (Jbig2SymbolDict *)jbig2_alloc(ctx->allocator,
sizeof(Jbig2SymbolDict));
if (new != NULL) {
new->glyphs = (Jbig2Image **)jbig2_alloc(ctx->allocator,
n_symbols*sizeof(Jbig2Image*));
new->n_symbols = n_symbols;
} else {
return NULL;
}
 
if (new->glyphs != NULL) {
memset(new->glyphs, 0, n_symbols*sizeof(Jbig2Image*));
} else {
jbig2_free(ctx->allocator, new);
return NULL;
}
 
return new;
}
 
/* release the memory associated with a symbol dict */
void
jbig2_sd_release(Jbig2Ctx *ctx, Jbig2SymbolDict *dict)
{
int i;
 
if (dict == NULL) return;
for (i = 0; i < dict->n_symbols; i++)
if (dict->glyphs[i]) jbig2_image_release(ctx, dict->glyphs[i]);
jbig2_free(ctx->allocator, dict->glyphs);
jbig2_free(ctx->allocator, dict);
}
 
/* get a particular glyph by index */
Jbig2Image *
jbig2_sd_glyph(Jbig2SymbolDict *dict, unsigned int id)
{
if (dict == NULL) return NULL;
return dict->glyphs[id];
}
 
/* count the number of dictionary segments referred to by the given segment */
int
jbig2_sd_count_referred(Jbig2Ctx *ctx, Jbig2Segment *segment)
{
int index;
Jbig2Segment *rsegment;
int n_dicts = 0;
 
for (index = 0; index < segment->referred_to_segment_count; index++) {
rsegment = jbig2_find_segment(ctx, segment->referred_to_segments[index]);
if (rsegment && ((rsegment->flags & 63) == 0)) n_dicts++;
}
 
return (n_dicts);
}
 
/* return an array of pointers to symbol dictionaries referred to by the given segment */
Jbig2SymbolDict **
jbig2_sd_list_referred(Jbig2Ctx *ctx, Jbig2Segment *segment)
{
int index;
Jbig2Segment *rsegment;
Jbig2SymbolDict **dicts;
int n_dicts = jbig2_sd_count_referred(ctx, segment);
int dindex = 0;
 
dicts = jbig2_alloc(ctx->allocator, sizeof(Jbig2SymbolDict *) * n_dicts);
for (index = 0; index < segment->referred_to_segment_count; index++) {
rsegment = jbig2_find_segment(ctx, segment->referred_to_segments[index]);
if (rsegment && ((rsegment->flags & 63) == 0)) {
/* add this referred to symbol dictionary */
dicts[dindex++] = (Jbig2SymbolDict *)rsegment->result;
}
}
 
if (dindex != n_dicts) {
/* should never happen */
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"counted %d symbol dictionaries but build a list with %d.\n",
n_dicts, dindex);
}
 
return (dicts);
}
 
/* generate a new symbol dictionary by concatenating a list of
existing dictionaries */
Jbig2SymbolDict *
jbig2_sd_cat(Jbig2Ctx *ctx, int n_dicts, Jbig2SymbolDict **dicts)
{
int i,j,k, symbols;
Jbig2SymbolDict *new = NULL;
 
/* count the imported symbols and allocate a new array */
symbols = 0;
for(i = 0; i < n_dicts; i++)
symbols += dicts[i]->n_symbols;
 
/* fill a new array with cloned glyph pointers */
new = jbig2_sd_new(ctx, symbols);
if (new != NULL) {
k = 0;
for (i = 0; i < n_dicts; i++)
for (j = 0; j < dicts[i]->n_symbols; j++)
new->glyphs[k++] = jbig2_image_clone(ctx, dicts[i]->glyphs[j]);
}
 
return new;
}
 
 
/* Decoding routines */
 
/* 6.5 */
static Jbig2SymbolDict *
jbig2_decode_symbol_dict(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2SymbolDictParams *params,
const byte *data, size_t size,
Jbig2ArithCx *GB_stats,
Jbig2ArithCx *GR_stats)
{
Jbig2SymbolDict *SDNEWSYMS;
Jbig2SymbolDict *SDEXSYMS;
int32_t HCHEIGHT;
uint32_t NSYMSDECODED;
int32_t SYMWIDTH, TOTWIDTH;
uint32_t HCFIRSTSYM;
uint32_t *SDNEWSYMWIDTHS = NULL;
int SBSYMCODELEN = 0;
Jbig2WordStream *ws = NULL;
Jbig2HuffmanState *hs = NULL;
Jbig2HuffmanTable *SDHUFFRDX = NULL;
Jbig2ArithState *as = NULL;
Jbig2ArithIntCtx *IADH = NULL;
Jbig2ArithIntCtx *IADW = NULL;
Jbig2ArithIntCtx *IAEX = NULL;
Jbig2ArithIntCtx *IAAI = NULL;
Jbig2ArithIaidCtx *IAID = NULL;
Jbig2ArithIntCtx *IARDX = NULL;
Jbig2ArithIntCtx *IARDY = NULL;
int code = 0;
Jbig2SymbolDict **refagg_dicts;
int n_refagg_dicts = 1;
 
Jbig2TextRegionParams *tparams = NULL;
 
/* 6.5.5 (3) */
HCHEIGHT = 0;
NSYMSDECODED = 0;
 
ws = jbig2_word_stream_buf_new(ctx, data, size);
 
if (!params->SDHUFF) {
as = jbig2_arith_new(ctx, ws);
IADH = jbig2_arith_int_ctx_new(ctx);
IADW = jbig2_arith_int_ctx_new(ctx);
IAEX = jbig2_arith_int_ctx_new(ctx);
IAAI = jbig2_arith_int_ctx_new(ctx);
if (params->SDREFAGG) {
int tmp = params->SDINSYMS->n_symbols + params->SDNUMNEWSYMS;
for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) < tmp; SBSYMCODELEN++);
IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
IARDX = jbig2_arith_int_ctx_new(ctx);
IARDY = jbig2_arith_int_ctx_new(ctx);
}
} else {
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"huffman coded symbol dictionary");
hs = jbig2_huffman_new(ctx, ws);
SDHUFFRDX = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O);
if (!params->SDREFAGG) {
SDNEWSYMWIDTHS = jbig2_alloc(ctx->allocator,
sizeof(*SDNEWSYMWIDTHS)*params->SDNUMNEWSYMS);
if (SDNEWSYMWIDTHS == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"could not allocate storage for symbol widths");
return NULL;
}
}
}
 
SDNEWSYMS = jbig2_sd_new(ctx, params->SDNUMNEWSYMS);
 
/* 6.5.5 (4a) */
while (NSYMSDECODED < params->SDNUMNEWSYMS) {
int32_t HCDH, DW;
 
/* 6.5.6 */
if (params->SDHUFF) {
HCDH = jbig2_huffman_get(hs, params->SDHUFFDH, &code);
} else {
code = jbig2_arith_int_decode(IADH, as, &HCDH);
}
 
if (code != 0) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"error or OOB decoding height class delta (%d)\n", code);
}
 
/* 6.5.5 (4b) */
HCHEIGHT = HCHEIGHT + HCDH;
SYMWIDTH = 0;
TOTWIDTH = 0;
HCFIRSTSYM = NSYMSDECODED;
 
if (HCHEIGHT < 0) {
/* todo: mem cleanup */
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Invalid HCHEIGHT value");
return NULL;
}
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"HCHEIGHT = %d", HCHEIGHT);
#endif
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"decoding height class %d with %d syms decoded", HCHEIGHT, NSYMSDECODED);
 
for (;;) {
/* check for broken symbol table */
if (NSYMSDECODED > params->SDNUMNEWSYMS)
{
/* todo: mem cleanup? */
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"No OOB signalling end of height class %d", HCHEIGHT);
break;
}
/* 6.5.7 */
if (params->SDHUFF) {
DW = jbig2_huffman_get(hs, params->SDHUFFDW, &code);
} else {
code = jbig2_arith_int_decode(IADW, as, &DW);
}
 
/* 6.5.5 (4c.i) */
if (code == 1) {
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
" OOB signals end of height class %d", HCHEIGHT);
break;
}
SYMWIDTH = SYMWIDTH + DW;
TOTWIDTH = TOTWIDTH + SYMWIDTH;
if (SYMWIDTH < 0) {
/* todo: mem cleanup */
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Invalid SYMWIDTH value (%d) at symbol %d", SYMWIDTH, NSYMSDECODED+1);
return NULL;
}
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"SYMWIDTH = %d TOTWIDTH = %d", SYMWIDTH, TOTWIDTH);
#endif
/* 6.5.5 (4c.ii) */
if (!params->SDHUFF || params->SDREFAGG) {
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"SDHUFF = %d; SDREFAGG = %d", params->SDHUFF, params->SDREFAGG);
#endif
/* 6.5.8 */
if (!params->SDREFAGG) {
Jbig2GenericRegionParams region_params;
int sdat_bytes;
Jbig2Image *image;
 
/* Table 16 */
region_params.MMR = 0;
region_params.GBTEMPLATE = params->SDTEMPLATE;
region_params.TPGDON = 0;
region_params.USESKIP = 0;
sdat_bytes = params->SDTEMPLATE == 0 ? 8 : 2;
memcpy(region_params.gbat, params->sdat, sdat_bytes);
 
image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
 
code = jbig2_decode_generic_region(ctx, segment, &region_params,
as, image, GB_stats);
/* todo: handle errors */
 
SDNEWSYMS->glyphs[NSYMSDECODED] = image;
 
} else {
/* 6.5.8.2 refinement/aggregate symbol */
uint32_t REFAGGNINST;
 
if (params->SDHUFF) {
REFAGGNINST = jbig2_huffman_get(hs, params->SDHUFFAGGINST, &code);
} else {
code = jbig2_arith_int_decode(IAAI, as, (int32_t*)&REFAGGNINST);
}
if (code || (int32_t)REFAGGNINST <= 0) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"invalid number of symbols or OOB in aggregate glyph");
return NULL;
}
 
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"aggregate symbol coding (%d instances)", REFAGGNINST);
 
if (REFAGGNINST > 1) {
Jbig2Image *image;
int i;
 
if (tparams == NULL)
{
/* First time through, we need to initialise the */
/* various tables for Huffman or adaptive encoding */
/* as well as the text region parameters structure */
refagg_dicts = jbig2_alloc(ctx->allocator, sizeof(Jbig2SymbolDict *) * n_refagg_dicts);
if (refagg_dicts == NULL) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Out of memory allocating dictionary array");
return NULL;
}
refagg_dicts[0] = jbig2_sd_new(ctx, params->SDNUMINSYMS + params->SDNUMNEWSYMS);
if (refagg_dicts[0] == NULL) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Out of memory allocating symbol dictionary");
jbig2_free(ctx->allocator, refagg_dicts);
return NULL;
}
refagg_dicts[0]->n_symbols = params->SDNUMINSYMS + params->SDNUMNEWSYMS;
for (i=0;i < params->SDNUMINSYMS;i++)
{
refagg_dicts[0]->glyphs[i] = jbig2_image_clone(ctx, params->SDINSYMS->glyphs[i]);
}
 
tparams = jbig2_alloc(ctx->allocator, sizeof(Jbig2TextRegionParams));
if (tparams == NULL) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Out of memory creating text region params");
jbig2_sd_release(ctx, refagg_dicts[0]);
jbig2_free(ctx->allocator, refagg_dicts);
return NULL;
}
if (!params->SDHUFF) {
/* Values from Table 17, section 6.5.8.2 (2) */
tparams->IADT = jbig2_arith_int_ctx_new(ctx);
tparams->IAFS = jbig2_arith_int_ctx_new(ctx);
tparams->IADS = jbig2_arith_int_ctx_new(ctx);
tparams->IAIT = jbig2_arith_int_ctx_new(ctx);
/* Table 31 */
for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) <
(int)(params->SDNUMINSYMS + params->SDNUMNEWSYMS); SBSYMCODELEN++);
tparams->IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
tparams->IARI = jbig2_arith_int_ctx_new(ctx);
tparams->IARDW = jbig2_arith_int_ctx_new(ctx);
tparams->IARDH = jbig2_arith_int_ctx_new(ctx);
tparams->IARDX = jbig2_arith_int_ctx_new(ctx);
tparams->IARDY = jbig2_arith_int_ctx_new(ctx);
} else {
tparams->SBHUFFFS = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_F); /* Table B.6 */
tparams->SBHUFFDS = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_H); /* Table B.8 */
tparams->SBHUFFDT = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_K); /* Table B.11 */
tparams->SBHUFFRDW = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O); /* Table B.15 */
tparams->SBHUFFRDH = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O); /* Table B.15 */
tparams->SBHUFFRDX = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O); /* Table B.15 */
tparams->SBHUFFRDY = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O); /* Table B.15 */
}
tparams->SBHUFF = params->SDHUFF;
tparams->SBREFINE = 1;
tparams->SBSTRIPS = 1;
tparams->SBDEFPIXEL = 0;
tparams->SBCOMBOP = JBIG2_COMPOSE_OR;
tparams->TRANSPOSED = 0;
tparams->REFCORNER = JBIG2_CORNER_TOPLEFT;
tparams->SBDSOFFSET = 0;
tparams->SBRTEMPLATE = params->SDRTEMPLATE;
}
tparams->SBNUMINSTANCES = REFAGGNINST;
 
image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
if (image == NULL) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Out of memory creating symbol image");
jbig2_free(ctx->allocator, tparams);
jbig2_sd_release(ctx, refagg_dicts[0]);
jbig2_free(ctx->allocator, refagg_dicts);
return NULL;
}
 
/* multiple symbols are handled as a text region */
jbig2_decode_text_region(ctx, segment, tparams, (const Jbig2SymbolDict * const *)refagg_dicts,
n_refagg_dicts, image, data, size, GR_stats, as, (Jbig2WordStream *)NULL);
 
SDNEWSYMS->glyphs[NSYMSDECODED] = image;
refagg_dicts[0]->glyphs[params->SDNUMINSYMS + NSYMSDECODED] = jbig2_image_clone(ctx, SDNEWSYMS->glyphs[NSYMSDECODED]);
} else {
/* 6.5.8.2.2 */
/* bool SBHUFF = params->SDHUFF; */
Jbig2RefinementRegionParams rparams;
Jbig2Image *image;
uint32_t ID;
int32_t RDX, RDY;
int ninsyms = params->SDINSYMS->n_symbols;
 
if (params->SDHUFF) {
ID = jbig2_huffman_get_bits(hs, SBSYMCODELEN);
RDX = jbig2_huffman_get(hs, SDHUFFRDX, &code);
RDY = jbig2_huffman_get(hs, SDHUFFRDX, &code);
} else {
code = jbig2_arith_iaid_decode(IAID, as, (int32_t*)&ID);
code = jbig2_arith_int_decode(IARDX, as, &RDX);
code = jbig2_arith_int_decode(IARDY, as, &RDY);
}
 
if (ID >= ninsyms+NSYMSDECODED) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"refinement references unknown symbol %d", ID);
return NULL;
}
 
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"symbol is a refinement of id %d with the refinement applied at (%d,%d)",
ID, RDX, RDY);
 
image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
 
/* Table 18 */
rparams.GRTEMPLATE = params->SDRTEMPLATE;
rparams.reference = (ID < ninsyms) ?
params->SDINSYMS->glyphs[ID] :
SDNEWSYMS->glyphs[ID-ninsyms];
rparams.DX = RDX;
rparams.DY = RDY;
rparams.TPGRON = 0;
memcpy(rparams.grat, params->sdrat, 4);
jbig2_decode_refinement_region(ctx, segment,
&rparams, as, image, GR_stats);
 
SDNEWSYMS->glyphs[NSYMSDECODED] = image;
 
}
}
 
#ifdef OUTPUT_PBM
{
char name[64];
FILE *out;
snprintf(name, 64, "sd.%04d.%04d.pbm",
segment->number, NSYMSDECODED);
out = fopen(name, "wb");
jbig2_image_write_pbm(SDNEWSYMS->glyphs[NSYMSDECODED], out);
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"writing out glyph as '%s' ...", name);
fclose(out);
}
#endif
 
}
 
/* 6.5.5 (4c.iii) */
if (params->SDHUFF && !params->SDREFAGG) {
SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH;
}
 
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"decoded symbol %d of %d (%dx%d)",
NSYMSDECODED, params->SDNUMNEWSYMS,
SYMWIDTH, HCHEIGHT);
 
/* 6.5.5 (4c.iv) */
NSYMSDECODED = NSYMSDECODED + 1;
 
} /* end height class decode loop */
 
/* 6.5.5 (4d) */
if (params->SDHUFF && !params->SDREFAGG) {
/* 6.5.9 */
Jbig2Image *image;
int BMSIZE = jbig2_huffman_get(hs, params->SDHUFFBMSIZE, &code);
int j, x;
 
if (code || (BMSIZE < 0)) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"error decoding size of collective bitmap!");
/* todo: memory cleanup */
return NULL;
}
 
/* skip any bits before the next byte boundary */
jbig2_huffman_skip(hs);
 
image = jbig2_image_new(ctx, TOTWIDTH, HCHEIGHT);
if (image == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"could not allocate collective bitmap image!");
/* todo: memory cleanup */
return NULL;
}
 
if (BMSIZE == 0) {
/* if BMSIZE == 0 bitmap is uncompressed */
const byte *src = data + jbig2_huffman_offset(hs);
const int stride = (image->width >> 3) +
((image->width & 7) ? 1 : 0);
byte *dst = image->data;
 
BMSIZE = image->height * stride;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"reading %dx%d uncompressed bitmap"
" for %d symbols (%d bytes)",
image->width, image->height, NSYMSDECODED - HCFIRSTSYM, BMSIZE);
 
for (j = 0; j < image->height; j++) {
memcpy(dst, src, stride);
dst += image->stride;
src += stride;
}
} else {
Jbig2GenericRegionParams rparams;
 
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"reading %dx%d collective bitmap for %d symbols (%d bytes)",
image->width, image->height, NSYMSDECODED - HCFIRSTSYM, BMSIZE);
 
rparams.MMR = 1;
code = jbig2_decode_generic_mmr(ctx, segment, &rparams,
data + jbig2_huffman_offset(hs), BMSIZE, image);
if (code) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"error decoding MMR bitmap image!");
/* todo: memory cleanup */
return NULL;
}
}
 
/* advance past the data we've just read */
jbig2_huffman_advance(hs, BMSIZE);
 
/* copy the collective bitmap into the symbol dictionary */
x = 0;
for (j = HCFIRSTSYM; j < NSYMSDECODED; j++) {
Jbig2Image *glyph;
glyph = jbig2_image_new(ctx, SDNEWSYMWIDTHS[j], HCHEIGHT);
jbig2_image_compose(ctx, glyph, image,
-x, 0, JBIG2_COMPOSE_REPLACE);
x += SDNEWSYMWIDTHS[j];
SDNEWSYMS->glyphs[j] = glyph;
}
jbig2_image_release(ctx, image);
}
 
} /* end of symbol decode loop */
 
if (tparams != NULL)
{
if (!params->SDHUFF)
{
jbig2_arith_int_ctx_free(ctx, tparams->IADT);
jbig2_arith_int_ctx_free(ctx, tparams->IAFS);
jbig2_arith_int_ctx_free(ctx, tparams->IADS);
jbig2_arith_int_ctx_free(ctx, tparams->IAIT);
jbig2_arith_iaid_ctx_free(ctx, tparams->IAID);
jbig2_arith_int_ctx_free(ctx, tparams->IARI);
jbig2_arith_int_ctx_free(ctx, tparams->IARDW);
jbig2_arith_int_ctx_free(ctx, tparams->IARDH);
jbig2_arith_int_ctx_free(ctx, tparams->IARDX);
jbig2_arith_int_ctx_free(ctx, tparams->IARDY);
}
else
{
jbig2_release_huffman_table(ctx, tparams->SBHUFFFS);
jbig2_release_huffman_table(ctx, tparams->SBHUFFDS);
jbig2_release_huffman_table(ctx, tparams->SBHUFFDT);
jbig2_release_huffman_table(ctx, tparams->SBHUFFRDX);
jbig2_release_huffman_table(ctx, tparams->SBHUFFRDY);
jbig2_release_huffman_table(ctx, tparams->SBHUFFRDW);
jbig2_release_huffman_table(ctx, tparams->SBHUFFRDH);
}
jbig2_free(ctx->allocator, tparams);
tparams = NULL;
jbig2_sd_release(ctx, refagg_dicts[0]);
jbig2_free(ctx->allocator, refagg_dicts);
}
 
jbig2_free(ctx->allocator, GB_stats);
 
/* 6.5.10 */
SDEXSYMS = jbig2_sd_new(ctx, params->SDNUMEXSYMS);
{
int i = 0;
int j = 0;
int k, m, exflag = 0;
int32_t exrunlength;
 
if (params->SDINSYMS != NULL)
m = params->SDINSYMS->n_symbols;
else
m = 0;
while (j < params->SDNUMEXSYMS) {
if (params->SDHUFF)
/* FIXME: implement reading from huff table B.1 */
exrunlength = params->SDNUMEXSYMS;
else
code = jbig2_arith_int_decode(IAEX, as, &exrunlength);
if (exrunlength > params->SDNUMEXSYMS - j) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"runlength too large in export symbol table (%d > %d - %d)\n",
exrunlength, params->SDNUMEXSYMS, j);
jbig2_sd_release(ctx, SDEXSYMS);
/* skip to the cleanup code and return SDEXSYMS = NULL */
SDEXSYMS = NULL;
break;
}
for(k = 0; k < exrunlength; k++)
if (exflag) {
SDEXSYMS->glyphs[j++] = (i < m) ?
jbig2_image_clone(ctx, params->SDINSYMS->glyphs[i]) :
jbig2_image_clone(ctx, SDNEWSYMS->glyphs[i-m]);
i++;
}
exflag = !exflag;
}
}
 
jbig2_sd_release(ctx, SDNEWSYMS);
 
if (!params->SDHUFF) {
jbig2_arith_int_ctx_free(ctx, IADH);
jbig2_arith_int_ctx_free(ctx, IADW);
jbig2_arith_int_ctx_free(ctx, IAEX);
jbig2_arith_int_ctx_free(ctx, IAAI);
if (params->SDREFAGG) {
jbig2_arith_iaid_ctx_free(ctx, IAID);
jbig2_arith_int_ctx_free(ctx, IARDX);
jbig2_arith_int_ctx_free(ctx, IARDY);
}
jbig2_free(ctx->allocator, as);
} else {
if (params->SDREFAGG) {
jbig2_free(ctx->allocator, SDNEWSYMWIDTHS);
}
jbig2_release_huffman_table(ctx, SDHUFFRDX);
jbig2_free(ctx->allocator, hs);
}
 
jbig2_word_stream_buf_free(ctx, ws);
 
return SDEXSYMS;
}
 
/* 7.4.2 */
int
jbig2_symbol_dictionary(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data)
{
Jbig2SymbolDictParams params;
uint16_t flags;
int sdat_bytes;
int offset;
Jbig2ArithCx *GB_stats = NULL;
Jbig2ArithCx *GR_stats = NULL;
 
if (segment->data_length < 10)
goto too_short;
 
/* 7.4.2.1.1 */
flags = jbig2_get_int16(segment_data);
params.SDHUFF = flags & 1;
params.SDREFAGG = (flags >> 1) & 1;
params.SDTEMPLATE = (flags >> 10) & 3;
params.SDRTEMPLATE = (flags >> 12) & 1;
 
params.SDHUFFDH = NULL;
params.SDHUFFDW = NULL;
params.SDHUFFBMSIZE = NULL;
params.SDHUFFAGGINST = NULL;
 
if (params.SDHUFF) {
switch ((flags & 0x000c) >> 2) {
case 0: /* Table B.4 */
params.SDHUFFDH = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_D);
break;
case 1: /* Table B.5 */
params.SDHUFFDH = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_E);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"symbol dictionary uses custom DH huffman table (NYI)");
case 2:
default:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"symbol dictionary specified invalid huffman table");
break;
}
switch ((flags & 0x0030) >> 4) {
case 0: /* Table B.2 */
params.SDHUFFDW = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_B);
break;
case 1: /* Table B.3 */
params.SDHUFFDW = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_C);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"symbol dictionary uses custom DW huffman table (NYI)");
case 2:
default:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"symbol dictionary specified invalid huffman table");
break;
}
if (flags & 0x0040) {
/* Custom table from referred segment */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"symbol dictionary uses custom BMSIZE huffman table (NYI)");
} else {
/* Table B.1 */
params.SDHUFFBMSIZE = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_A);
}
if (flags & 0x0080) {
/* Custom table from referred segment */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"symbol dictionary uses custom REFAGG huffman table (NYI)");
} else {
/* Table B.1 */
params.SDHUFFAGGINST = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_A);
}
}
 
/* FIXME: there are quite a few of these conditions to check */
/* maybe #ifdef CONFORMANCE and a separate routine */
if (!params.SDHUFF) {
if (flags & 0x000c) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"SDHUFF is zero, but contrary to spec SDHUFFDH is not.");
}
if (flags & 0x0030) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"SDHUFF is zero, but contrary to spec SDHUFFDW is not.");
}
}
 
if (flags & 0x0080) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"bitmap coding context is used (NYI) symbol data likely to be garbage!");
}
 
/* 7.4.2.1.2 */
sdat_bytes = params.SDHUFF ? 0 : params.SDTEMPLATE == 0 ? 8 : 2;
memcpy(params.sdat, segment_data + 2, sdat_bytes);
offset = 2 + sdat_bytes;
 
/* 7.4.2.1.3 */
if (params.SDREFAGG && !params.SDRTEMPLATE) {
if (offset + 4 > segment->data_length)
goto too_short;
memcpy(params.sdrat, segment_data + offset, 4);
offset += 4;
} else {
/* sdrat is meaningless if SDRTEMPLATE is 1, but set a value
to avoid confusion if anybody looks */
memset(params.sdrat, 0, 4);
}
 
if (offset + 8 > segment->data_length)
goto too_short;
 
/* 7.4.2.1.4 */
params.SDNUMEXSYMS = jbig2_get_int32(segment_data + offset);
/* 7.4.2.1.5 */
params.SDNUMNEWSYMS = jbig2_get_int32(segment_data + offset + 4);
offset += 8;
 
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"symbol dictionary, flags=%04x, %d exported syms, %d new syms",
flags, params.SDNUMEXSYMS, params.SDNUMNEWSYMS);
 
/* 7.4.2.2 (2) */
{
int n_dicts = jbig2_sd_count_referred(ctx, segment);
Jbig2SymbolDict **dicts = NULL;
 
params.SDINSYMS = NULL;
if (n_dicts > 0) {
dicts = jbig2_sd_list_referred(ctx, segment);
params.SDINSYMS = jbig2_sd_cat(ctx, n_dicts, dicts);
}
if (params.SDINSYMS != NULL) {
params.SDNUMINSYMS = params.SDINSYMS->n_symbols;
} else {
params.SDNUMINSYMS = 0;
}
}
 
/* 7.4.2.2 (4) */
if (!params.SDHUFF) {
int stats_size = params.SDTEMPLATE == 0 ? 65536 :
params.SDTEMPLATE == 1 ? 8192 : 1024;
GB_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GB_stats, 0, stats_size);
if (params.SDREFAGG) {
stats_size = params.SDRTEMPLATE ? 1 << 10 : 1 << 13;
GR_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GR_stats, 0, stats_size);
}
}
 
if (flags & 0x0100) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"segment marks bitmap coding context as retained (NYI)");
}
 
segment->result = (void *)jbig2_decode_symbol_dict(ctx, segment,
&params,
segment_data + offset,
segment->data_length - offset,
GB_stats, GR_stats);
#ifdef DUMP_SYMDICT
if (segment->result) jbig2_dump_symbol_dict(ctx, segment);
#endif
 
if (params.SDHUFF) {
jbig2_release_huffman_table(ctx, params.SDHUFFDH);
jbig2_release_huffman_table(ctx, params.SDHUFFDW);
jbig2_release_huffman_table(ctx, params.SDHUFFBMSIZE);
jbig2_release_huffman_table(ctx, params.SDHUFFAGGINST);
}
 
/* todo: retain or free GB_stats, GR_stats */
 
return (segment->result != NULL) ? 0 : -1;
 
too_short:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_symbol_dict.h
0,0 → 1,56
/*
jbig2dec
 
Copyright (C) 2001-2002 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/* symbol dictionary header */
 
/* the results of decoding a symbol dictionary */
typedef struct {
int n_symbols;
Jbig2Image **glyphs;
} Jbig2SymbolDict;
 
/* decode a symbol dictionary segment and store the results */
int
jbig2_symbol_dictionary(Jbig2Ctx *ctx, Jbig2Segment *segment,
const byte *segment_data);
 
/* get a particular glyph by index */
Jbig2Image *
jbig2_sd_glyph(Jbig2SymbolDict *dict, unsigned int id);
 
/* return a new empty symbol dict */
Jbig2SymbolDict *
jbig2_sd_new(Jbig2Ctx *ctx, int n_symbols);
 
/* release the memory associated with a symbol dict */
void
jbig2_sd_release(Jbig2Ctx *ctx, Jbig2SymbolDict *dict);
 
/* generate a new symbol dictionary by concatenating a list of
existing dictionaries */
Jbig2SymbolDict *
jbig2_sd_cat(Jbig2Ctx *ctx, int n_dicts,
Jbig2SymbolDict **dicts);
 
/* count the number of dictionary segments referred
to by the given segment */
int
jbig2_sd_count_referred(Jbig2Ctx *ctx, Jbig2Segment *segment);
 
/* return an array of pointers to symbol dictionaries referred
to by a segment */
Jbig2SymbolDict **
jbig2_sd_list_referred(Jbig2Ctx *ctx, Jbig2Segment *segment);
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_text.c
0,0 → 1,787
/*
jbig2dec
 
Copyright (C) 2002-2008 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_types.h"
 
#include <stddef.h>
#include <string.h> /* memset() */
 
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_arith_int.h"
#include "jbig2_arith_iaid.h"
#include "jbig2_huffman.h"
#include "jbig2_generic.h"
#include "jbig2_symbol_dict.h"
#include "jbig2_text.h"
 
 
/**
* jbig2_decode_text_region: decode a text region segment
*
* @ctx: jbig2 decoder context
* @segment: jbig2 segment (header) structure
* @params: parameters from the text region header
* @dicts: an array of referenced symbol dictionaries
* @n_dicts: the number of referenced symbol dictionaries
* @image: image structure in which to store the decoded region bitmap
* @data: pointer to text region data to be decoded
* @size: length of text region data
*
* Implements the text region decoding procedure
* described in section 6.4 of the JBIG2 spec.
*
* returns: 0 on success
**/
int
jbig2_decode_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const Jbig2TextRegionParams *params,
const Jbig2SymbolDict * const *dicts, const int n_dicts,
Jbig2Image *image,
const byte *data, const size_t size,
Jbig2ArithCx *GR_stats, Jbig2ArithState *as, Jbig2WordStream *ws)
{
/* relevent bits of 6.4.4 */
uint32_t NINSTANCES;
uint32_t ID;
int32_t STRIPT;
int32_t FIRSTS;
int32_t DT;
int32_t DFS;
int32_t IDS;
int32_t CURS;
int32_t CURT;
int S,T;
int x,y;
bool first_symbol;
uint32_t index, SBNUMSYMS;
Jbig2Image *IB;
Jbig2HuffmanState *hs = NULL;
Jbig2HuffmanTable *SBSYMCODES = NULL;
int code = 0;
int RI;
 
SBNUMSYMS = 0;
for (index = 0; index < n_dicts; index++) {
SBNUMSYMS += dicts[index]->n_symbols;
}
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"symbol list contains %d glyphs in %d dictionaries", SBNUMSYMS, n_dicts);
 
if (params->SBHUFF) {
Jbig2HuffmanTable *runcodes;
Jbig2HuffmanParams runcodeparams;
Jbig2HuffmanLine runcodelengths[35];
Jbig2HuffmanLine *symcodelengths;
Jbig2HuffmanParams symcodeparams;
int code, err, len, range, r;
 
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"huffman coded text region");
hs = jbig2_huffman_new(ctx, ws);
 
/* 7.4.3.1.7 - decode symbol ID Huffman table */
/* this is actually part of the segment header, but it is more
convenient to handle it here */
 
/* parse and build the runlength code huffman table */
for (index = 0; index < 35; index++) {
runcodelengths[index].PREFLEN = jbig2_huffman_get_bits(hs, 4);
runcodelengths[index].RANGELEN = 0;
runcodelengths[index].RANGELOW = index;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
" read runcode%d length %d", index, runcodelengths[index].PREFLEN);
}
runcodeparams.HTOOB = 0;
runcodeparams.lines = runcodelengths;
runcodeparams.n_lines = 35;
runcodes = jbig2_build_huffman_table(ctx, &runcodeparams);
if (runcodes == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"error constructing symbol id runcode table!");
return -1;
}
 
/* decode the symbol id codelengths using the runlength table */
symcodelengths = jbig2_alloc(ctx->allocator, SBNUMSYMS*sizeof(Jbig2HuffmanLine));
if (symcodelengths == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"memory allocation failure reading symbol ID huffman table!");
return -1;
}
index = 0;
while (index < SBNUMSYMS) {
code = jbig2_huffman_get(hs, runcodes, &err);
if (err != 0 || code < 0 || code >= 35) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"error reading symbol ID huffman table!");
return err ? err : -1;
}
 
if (code < 32) {
len = code;
range = 1;
} else {
if (code == 32) {
len = symcodelengths[index-1].PREFLEN;
if (index < 1) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"error decoding symbol id table: run length with no antecedent!");
/* todo: memory cleanup */
return -1;
}
} else {
len = 0; /* code == 33 or 34 */
}
if (code == 32) range = jbig2_huffman_get_bits(hs, 2) + 3;
else if (code == 33) range = jbig2_huffman_get_bits(hs, 3) + 3;
else if (code == 34) range = jbig2_huffman_get_bits(hs, 7) + 11;
}
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
" read runcode%d at index %d (length %d range %d)", code, index, len, range);
if (index+range > SBNUMSYMS) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"runlength extends %d entries beyond the end of symbol id table!",
index+range - SBNUMSYMS);
range = SBNUMSYMS - index;
}
for (r = 0; r < range; r++) {
symcodelengths[index+r].PREFLEN = len;
symcodelengths[index+r].RANGELEN = 0;
symcodelengths[index+r].RANGELOW = index + r;
}
index += r;
}
 
if (index < SBNUMSYMS) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"runlength codes do not cover the available symbol set");
}
symcodeparams.HTOOB = 0;
symcodeparams.lines = symcodelengths;
symcodeparams.n_lines = SBNUMSYMS;
 
/* skip to byte boundary */
jbig2_huffman_skip(hs);
 
/* finally, construct the symbol id huffman table itself */
SBSYMCODES = jbig2_build_huffman_table(ctx, &symcodeparams);
 
jbig2_free(ctx->allocator, symcodelengths);
jbig2_release_huffman_table(ctx, runcodes);
 
if (SBSYMCODES == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"could not construct Symbol ID huffman table!");
return -1;
}
}
 
/* 6.4.5 (1) */
jbig2_image_clear(ctx, image, params->SBDEFPIXEL);
 
/* 6.4.6 */
if (params->SBHUFF) {
STRIPT = jbig2_huffman_get(hs, params->SBHUFFDT, &code);
} else {
code = jbig2_arith_int_decode(params->IADT, as, &STRIPT);
}
 
/* 6.4.5 (2) */
STRIPT *= -(params->SBSTRIPS);
FIRSTS = 0;
NINSTANCES = 0;
 
/* 6.4.5 (3) */
while (NINSTANCES < params->SBNUMINSTANCES) {
/* (3b) */
if (params->SBHUFF) {
DT = jbig2_huffman_get(hs, params->SBHUFFDT, &code);
} else {
code = jbig2_arith_int_decode(params->IADT, as, &DT);
}
DT *= params->SBSTRIPS;
STRIPT += DT;
 
first_symbol = TRUE;
/* 6.4.5 (3c) - decode symbols in strip */
for (;;) {
/* (3c.i) */
if (first_symbol) {
/* 6.4.7 */
if (params->SBHUFF) {
DFS = jbig2_huffman_get(hs, params->SBHUFFFS, &code);
} else {
code = jbig2_arith_int_decode(params->IAFS, as, &DFS);
}
FIRSTS += DFS;
CURS = FIRSTS;
first_symbol = FALSE;
 
} else {
/* (3c.ii) / 6.4.8 */
if (params->SBHUFF) {
IDS = jbig2_huffman_get(hs, params->SBHUFFDS, &code);
} else {
code = jbig2_arith_int_decode(params->IADS, as, &IDS);
}
if (code) {
break;
}
CURS += IDS + params->SBDSOFFSET;
}
 
/* (3c.iii) / 6.4.9 */
if (params->SBSTRIPS == 1) {
CURT = 0;
} else if (params->SBHUFF) {
CURT = jbig2_huffman_get_bits(hs, params->LOGSBSTRIPS);
} else {
code = jbig2_arith_int_decode(params->IAIT, as, &CURT);
}
T = STRIPT + CURT;
 
/* (3b.iv) / 6.4.10 - decode the symbol id */
if (params->SBHUFF) {
ID = jbig2_huffman_get(hs, SBSYMCODES, &code);
} else {
code = jbig2_arith_iaid_decode(params->IAID, as, (int *)&ID);
}
if (ID >= SBNUMSYMS) {
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"symbol id out of range! (%d/%d)", ID, SBNUMSYMS);
}
 
/* (3c.v) / 6.4.11 - look up the symbol bitmap IB */
{
uint32_t id = ID;
 
index = 0;
while (id >= dicts[index]->n_symbols)
id -= dicts[index++]->n_symbols;
IB = jbig2_image_clone(ctx, dicts[index]->glyphs[id]);
}
if (params->SBREFINE) {
if (params->SBHUFF) {
RI = jbig2_huffman_get_bits(hs, 1);
} else {
code = jbig2_arith_int_decode(params->IARI, as, &RI);
}
} else {
RI = 0;
}
if (RI) {
Jbig2RefinementRegionParams rparams;
Jbig2Image *IBO;
int32_t RDW, RDH, RDX, RDY;
Jbig2Image *refimage;
int BMSIZE = 0;
 
/* 6.4.11 (1, 2, 3, 4) */
if (!params->SBHUFF) {
code = jbig2_arith_int_decode(params->IARDW, as, &RDW);
code = jbig2_arith_int_decode(params->IARDH, as, &RDH);
code = jbig2_arith_int_decode(params->IARDX, as, &RDX);
code = jbig2_arith_int_decode(params->IARDY, as, &RDY);
} else {
RDW = jbig2_huffman_get(hs, params->SBHUFFRDW, &code);
RDH = jbig2_huffman_get(hs, params->SBHUFFRDH, &code);
RDX = jbig2_huffman_get(hs, params->SBHUFFRDX, &code);
RDY = jbig2_huffman_get(hs, params->SBHUFFRDY, &code);
BMSIZE = jbig2_huffman_get(hs, params->SBHUFFRSIZE, &code);
jbig2_huffman_skip(hs);
}
 
/* 6.4.11 (6) */
IBO = IB;
refimage = jbig2_image_new(ctx, IBO->width + RDW,
IBO->height + RDH);
if (refimage == NULL) {
jbig2_image_release(ctx, IBO);
if (params->SBHUFF) {
jbig2_release_huffman_table(ctx, SBSYMCODES);
}
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL,
segment->number,
"couldn't allocate reference image");
}
 
/* Table 12 */
rparams.GRTEMPLATE = params->SBRTEMPLATE;
rparams.reference = IBO;
rparams.DX = (RDW >> 1) + RDX;
rparams.DY = (RDH >> 1) + RDY;
rparams.TPGRON = 0;
memcpy(rparams.grat, params->sbrat, 4);
jbig2_decode_refinement_region(ctx, segment,
&rparams, as, refimage, GR_stats);
IB = refimage;
 
jbig2_image_release(ctx, IBO);
 
/* 6.4.11 (7) */
if (params->SBHUFF) {
jbig2_huffman_advance(hs, BMSIZE);
}
 
}
 
/* (3c.vi) */
if ((!params->TRANSPOSED) && (params->REFCORNER > 1)) {
CURS += IB->width - 1;
} else if ((params->TRANSPOSED) && !(params->REFCORNER & 1)) {
CURS += IB->height - 1;
}
 
/* (3c.vii) */
S = CURS;
 
/* (3c.viii) */
if (!params->TRANSPOSED) {
switch (params->REFCORNER) {
case JBIG2_CORNER_TOPLEFT: x = S; y = T; break;
case JBIG2_CORNER_TOPRIGHT: x = S - IB->width + 1; y = T; break;
case JBIG2_CORNER_BOTTOMLEFT: x = S; y = T - IB->height + 1; break;
case JBIG2_CORNER_BOTTOMRIGHT: x = S - IB->width + 1; y = T - IB->height + 1; break;
}
} else { /* TRANSPOSED */
switch (params->REFCORNER) {
case JBIG2_CORNER_TOPLEFT: x = T; y = S; break;
case JBIG2_CORNER_TOPRIGHT: x = T - IB->width + 1; y = S; break;
case JBIG2_CORNER_BOTTOMLEFT: x = T; y = S - IB->height + 1; break;
case JBIG2_CORNER_BOTTOMRIGHT: x = T - IB->width + 1; y = S - IB->height + 1; break;
}
}
 
/* (3c.ix) */
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"composing glyph id %d: %dx%d @ (%d,%d) symbol %d/%d",
ID, IB->width, IB->height, x, y, NINSTANCES + 1,
params->SBNUMINSTANCES);
#endif
jbig2_image_compose(ctx, image, IB, x, y, params->SBCOMBOP);
 
/* (3c.x) */
if ((!params->TRANSPOSED) && (params->REFCORNER < 2)) {
CURS += IB->width -1 ;
} else if ((params->TRANSPOSED) && (params->REFCORNER & 1)) {
CURS += IB->height - 1;
}
 
/* (3c.xi) */
NINSTANCES++;
 
jbig2_image_release(ctx, IB);
}
/* end strip */
}
/* 6.4.5 (4) */
 
if (params->SBHUFF) {
jbig2_release_huffman_table(ctx, SBSYMCODES);
}
 
return 0;
}
 
/**
* jbig2_text_region: read a text region segment header
**/
int
jbig2_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment, const byte *segment_data)
{
int offset = 0;
Jbig2RegionSegmentInfo region_info;
Jbig2TextRegionParams params;
Jbig2Image *image;
Jbig2SymbolDict **dicts;
int n_dicts;
uint16_t flags;
uint16_t huffman_flags = 0;
Jbig2ArithCx *GR_stats = NULL;
int code = 0;
Jbig2WordStream *ws = NULL;
Jbig2ArithState *as = NULL;
 
/* 7.4.1 */
if (segment->data_length < 17)
goto too_short;
jbig2_get_region_segment_info(&region_info, segment_data);
offset += 17;
 
/* 7.4.3.1.1 */
flags = jbig2_get_int16(segment_data + offset);
offset += 2;
 
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"text region header flags 0x%04x", flags);
 
params.SBHUFF = flags & 0x0001;
params.SBREFINE = flags & 0x0002;
params.LOGSBSTRIPS = (flags & 0x000c) >> 2;
params.SBSTRIPS = 1 << params.LOGSBSTRIPS;
params.REFCORNER = (flags & 0x0030) >> 4;
params.TRANSPOSED = flags & 0x0040;
params.SBCOMBOP = (flags & 0x0180) >> 7;
params.SBDEFPIXEL = flags & 0x0200;
/* SBDSOFFSET is a signed 5 bit integer */
params.SBDSOFFSET = (flags & 0x7C00) >> 10;
if (params.SBDSOFFSET > 0x0f) params.SBDSOFFSET -= 0x20;
params.SBRTEMPLATE = flags & 0x8000;
 
if (params.SBDSOFFSET) {
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"text region has SBDSOFFSET %d", params.SBDSOFFSET);
}
 
if (params.SBHUFF) /* Huffman coding */
{
/* 7.4.3.1.2 */
huffman_flags = jbig2_get_int16(segment_data + offset);
offset += 2;
 
if (huffman_flags & 0x8000)
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"reserved bit 15 of text region huffman flags is not zero");
}
else /* arithmetic coding */
{
/* 7.4.3.1.3 */
if ((params.SBREFINE) && !(params.SBRTEMPLATE))
{
params.sbrat[0] = segment_data[offset];
params.sbrat[1] = segment_data[offset + 1];
params.sbrat[2] = segment_data[offset + 2];
params.sbrat[3] = segment_data[offset + 3];
offset += 4;
} else {
/* zero these for the sake of later debug messages */
memset(params.sbrat, 0, sizeof(params.sbrat));
}
}
 
/* 7.4.3.1.4 */
params.SBNUMINSTANCES = jbig2_get_int32(segment_data + offset);
offset += 4;
 
if (params.SBHUFF) {
/* 7.4.3.1.5 - Symbol ID Huffman table */
/* ...this is handled in the segment body decoder */
 
/* 7.4.3.1.6 - Other Huffman table selection */
switch (huffman_flags & 0x0003) {
case 0: /* Table B.6 */
params.SBHUFFFS = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_F);
break;
case 1: /* Table B.7 */
params.SBHUFFFS = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_G);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom FS huffman table (NYI)");
break;
case 2: /* invalid */
default:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region specified invalid FS huffman table");
break;
}
switch ((huffman_flags & 0x000c) >> 2) {
case 0: /* Table B.8 */
params.SBHUFFDS = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_H);
break;
case 1: /* Table B.9 */
params.SBHUFFDS = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_I);
break;
case 2: /* Table B.10 */
params.SBHUFFDS = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_J);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom DS huffman table (NYI)");
break;
}
switch ((huffman_flags & 0x0030) >> 4) {
case 0: /* Table B.11 */
params.SBHUFFDT = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_K);
break;
case 1: /* Table B.12 */
params.SBHUFFDT = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_L);
break;
case 2: /* Table B.13 */
params.SBHUFFDT = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_M);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom DT huffman table (NYI)");
break;
}
switch ((huffman_flags & 0x00c0) >> 6) {
case 0: /* Table B.14 */
params.SBHUFFRDW = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_N);
break;
case 1: /* Table B.15 */
params.SBHUFFRDW = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom RDW huffman table (NYI)");
break;
case 2: /* invalid */
default:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region specified invalid RDW huffman table");
break;
}
switch ((huffman_flags & 0x0300) >> 8) {
case 0: /* Table B.14 */
params.SBHUFFRDH = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_N);
break;
case 1: /* Table B.15 */
params.SBHUFFRDH = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom RDH huffman table (NYI)");
break;
case 2: /* invalid */
default:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region specified invalid RDH huffman table");
break;
}
switch ((huffman_flags & 0x0c00) >> 10) {
case 0: /* Table B.14 */
params.SBHUFFRDX = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_N);
break;
case 1: /* Table B.15 */
params.SBHUFFRDX = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom RDX huffman table (NYI)");
break;
case 2: /* invalid */
default:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region specified invalid RDX huffman table");
break;
}
switch ((huffman_flags & 0x3000) >> 12) {
case 0: /* Table B.14 */
params.SBHUFFRDY = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_N);
break;
case 1: /* Table B.15 */
params.SBHUFFRDY = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_O);
break;
case 3: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom RDY huffman table (NYI)");
break;
case 2: /* invalid */
default:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region specified invalid RDY huffman table");
break;
}
switch ((huffman_flags & 0x4000) >> 14) {
case 0: /* Table B.1 */
params.SBHUFFRSIZE = jbig2_build_huffman_table(ctx,
&jbig2_huffman_params_A);
break;
case 1: /* Custom table from referred segment */
/* We handle this case later by leaving the table as NULL */
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region uses custom RSIZE huffman table (NYI)");
break;
}
 
if (huffman_flags & 0x8000) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"text region huffman flags bit 15 is set, contrary to spec");
}
 
/* 7.4.3.1.7 */
/* For convenience this is done in the body decoder routine */
}
 
jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
"text region: %d x %d @ (%d,%d) %d symbols",
region_info.width, region_info.height,
region_info.x, region_info.y, params.SBNUMINSTANCES);
 
/* 7.4.3.2 (2) - compose the list of symbol dictionaries */
n_dicts = jbig2_sd_count_referred(ctx, segment);
if (n_dicts != 0) {
dicts = jbig2_sd_list_referred(ctx, segment);
} else {
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"text region refers to no symbol dictionaries!");
}
if (dicts == NULL) {
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"unable to retrive symbol dictionaries!"
" previous parsing error?");
} else {
int index;
if (dicts[0] == NULL) {
return jbig2_error(ctx, JBIG2_SEVERITY_WARNING,
segment->number,
"unable to find first referenced symbol dictionary!");
}
for (index = 1; index < n_dicts; index++)
if (dicts[index] == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"unable to find all referenced symbol dictionaries!");
n_dicts = index;
}
}
 
/* 7.4.3.2 (3) */
if (!params.SBHUFF && params.SBREFINE) {
int stats_size = params.SBRTEMPLATE ? 1 << 10 : 1 << 13;
GR_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GR_stats, 0, stats_size);
}
 
image = jbig2_image_new(ctx, region_info.width, region_info.height);
if (image == NULL) {
if (!params.SBHUFF && params.SBREFINE) {
jbig2_free(ctx->allocator, GR_stats);
} else if (params.SBHUFF) {
jbig2_release_huffman_table(ctx, params.SBHUFFFS);
jbig2_release_huffman_table(ctx, params.SBHUFFDS);
jbig2_release_huffman_table(ctx, params.SBHUFFDT);
jbig2_release_huffman_table(ctx, params.SBHUFFRDX);
jbig2_release_huffman_table(ctx, params.SBHUFFRDY);
jbig2_release_huffman_table(ctx, params.SBHUFFRDW);
jbig2_release_huffman_table(ctx, params.SBHUFFRDH);
jbig2_release_huffman_table(ctx, params.SBHUFFRSIZE);
}
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"couldn't allocate text region image");
}
 
ws = jbig2_word_stream_buf_new(ctx, segment_data + offset, segment->data_length - offset);
if (!params.SBHUFF) {
int SBSYMCODELEN, index;
int SBNUMSYMS = 0;
for (index = 0; index < n_dicts; index++) {
SBNUMSYMS += dicts[index]->n_symbols;
}
 
as = jbig2_arith_new(ctx, ws);
ws = 0;
 
params.IADT = jbig2_arith_int_ctx_new(ctx);
params.IAFS = jbig2_arith_int_ctx_new(ctx);
params.IADS = jbig2_arith_int_ctx_new(ctx);
params.IAIT = jbig2_arith_int_ctx_new(ctx);
/* Table 31 */
for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) < SBNUMSYMS; SBSYMCODELEN++);
params.IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
params.IARI = jbig2_arith_int_ctx_new(ctx);
params.IARDW = jbig2_arith_int_ctx_new(ctx);
params.IARDH = jbig2_arith_int_ctx_new(ctx);
params.IARDX = jbig2_arith_int_ctx_new(ctx);
params.IARDY = jbig2_arith_int_ctx_new(ctx);
}
 
code = jbig2_decode_text_region(ctx, segment, &params,
(const Jbig2SymbolDict * const *)dicts, n_dicts, image,
segment_data + offset, segment->data_length - offset,
GR_stats, as, ws);
 
if (!params.SBHUFF && params.SBREFINE) {
jbig2_free(ctx->allocator, GR_stats);
}
 
if (params.SBHUFF) {
jbig2_release_huffman_table(ctx, params.SBHUFFFS);
jbig2_release_huffman_table(ctx, params.SBHUFFDS);
jbig2_release_huffman_table(ctx, params.SBHUFFDT);
jbig2_release_huffman_table(ctx, params.SBHUFFRDX);
jbig2_release_huffman_table(ctx, params.SBHUFFRDY);
jbig2_release_huffman_table(ctx, params.SBHUFFRDW);
jbig2_release_huffman_table(ctx, params.SBHUFFRDH);
jbig2_release_huffman_table(ctx, params.SBHUFFRSIZE);
}
else {
jbig2_arith_int_ctx_free(ctx, params.IADT);
jbig2_arith_int_ctx_free(ctx, params.IAFS);
jbig2_arith_int_ctx_free(ctx, params.IADS);
jbig2_arith_int_ctx_free(ctx, params.IAIT);
jbig2_arith_iaid_ctx_free(ctx, params.IAID);
jbig2_arith_int_ctx_free(ctx, params.IARI);
jbig2_arith_int_ctx_free(ctx, params.IARDW);
jbig2_arith_int_ctx_free(ctx, params.IARDH);
jbig2_arith_int_ctx_free(ctx, params.IARDX);
jbig2_arith_int_ctx_free(ctx, params.IARDY);
jbig2_free(ctx->allocator, as);
jbig2_word_stream_buf_free(ctx, ws);
}
 
jbig2_free(ctx->allocator, dicts);
 
/* todo: check errors */
 
if ((segment->flags & 63) == 4) {
/* we have an intermediate region here. save it for later */
segment->result = image;
} else {
/* otherwise composite onto the page */
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"composing %dx%d decoded text region onto page at (%d, %d)",
region_info.width, region_info.height, region_info.x, region_info.y);
jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image,
region_info.x, region_info.y, region_info.op);
jbig2_image_release(ctx, image);
}
 
/* success */
return 0;
 
too_short:
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Segment too short");
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2_text.h
0,0 → 1,73
/*
jbig2dec
 
Copyright (C) 2002-2004 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/**
* Headers for Text region handling
**/
 
typedef enum {
JBIG2_CORNER_BOTTOMLEFT = 0,
JBIG2_CORNER_TOPLEFT = 1,
JBIG2_CORNER_BOTTOMRIGHT = 2,
JBIG2_CORNER_TOPRIGHT = 3
} Jbig2RefCorner;
 
typedef struct {
bool SBHUFF;
bool SBREFINE;
bool SBDEFPIXEL;
Jbig2ComposeOp SBCOMBOP;
bool TRANSPOSED;
Jbig2RefCorner REFCORNER;
int SBDSOFFSET;
/* int SBW; */
/* int SBH; */
uint32_t SBNUMINSTANCES;
int LOGSBSTRIPS;
int SBSTRIPS;
/* int SBNUMSYMS; */
/* SBSYMCODES */
/* SBSYMCODELEN */
/* SBSYMS */
Jbig2HuffmanTable *SBHUFFFS;
Jbig2HuffmanTable *SBHUFFDS;
Jbig2HuffmanTable *SBHUFFDT;
Jbig2HuffmanTable *SBHUFFRDW;
Jbig2HuffmanTable *SBHUFFRDH;
Jbig2HuffmanTable *SBHUFFRDX;
Jbig2HuffmanTable *SBHUFFRDY;
Jbig2HuffmanTable *SBHUFFRSIZE;
Jbig2ArithIntCtx *IADT;
Jbig2ArithIntCtx *IAFS;
Jbig2ArithIntCtx *IADS;
Jbig2ArithIntCtx *IAIT;
Jbig2ArithIaidCtx *IAID;
Jbig2ArithIntCtx *IARI;
Jbig2ArithIntCtx *IARDW;
Jbig2ArithIntCtx *IARDH;
Jbig2ArithIntCtx *IARDX;
Jbig2ArithIntCtx *IARDY;
bool SBRTEMPLATE;
int8_t sbrat[4];
} Jbig2TextRegionParams;
 
int
jbig2_decode_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const Jbig2TextRegionParams *params,
const Jbig2SymbolDict * const *dicts, const int n_dicts,
Jbig2Image *image,
const byte *data, const size_t size,
Jbig2ArithCx *GR_stats,
Jbig2ArithState *as, Jbig2WordStream *ws);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/jbig2dec.c
0,0 → 1,513
/*
jbig2dec
 
Copyright (C) 2001-2009 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
 
#ifndef PACKAGE
#define PACKAGE "jbig2dec"
#endif
#ifndef VERSION
#define VERSION "unknown-version"
#endif
 
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
 
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#else
# include "getopt.h"
#endif
 
#include "os_types.h"
#include "sha1.h"
 
#include "jbig2.h"
#include "jbig2_image.h"
 
typedef enum {
usage,dump,render
} jbig2dec_mode;
 
typedef enum {
jbig2dec_format_jbig2,
jbig2dec_format_pbm,
jbig2dec_format_png,
jbig2dec_format_none
} jbig2dec_format;
 
typedef struct {
jbig2dec_mode mode;
int verbose, hash;
SHA1_CTX *hash_ctx;
char *output_file;
jbig2dec_format output_format;
} jbig2dec_params_t;
 
static int print_version(void);
static int print_usage(void);
 
/* page hashing functions */
static void
hash_init(jbig2dec_params_t *params)
{
params->hash_ctx = malloc(sizeof(SHA1_CTX));
if (params->hash_ctx == NULL) {
fprintf(stderr, "unable to allocate hash state\n");
params->hash = 0;
return;
} else {
SHA1_Init(params->hash_ctx);
}
}
 
static void
hash_image(jbig2dec_params_t *params, Jbig2Image *image)
{
unsigned int N = image->stride * image->height;
SHA1_Update(params->hash_ctx, image->data, N);
}
 
static void
hash_print(jbig2dec_params_t *params, FILE *out)
{
unsigned char md[SHA1_DIGEST_SIZE];
char digest[2*SHA1_DIGEST_SIZE + 1];
int i;
 
SHA1_Final(params->hash_ctx, md);
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
snprintf(&(digest[2*i]), 3, "%02x", md[i]);
}
fprintf(out, "%s", digest);
}
 
static void
hash_free(jbig2dec_params_t *params)
{
free(params->hash_ctx);
params->hash_ctx = NULL;
}
 
static int
set_output_format(jbig2dec_params_t *params, const char *format)
{
#ifdef HAVE_LIBPNG
/* this should really by strncasecmp()
TODO: we need to provide our own for portability */
if (!strncmp(format, "png", 3) || !strncmp(format, "PNG", 3)) {
params->output_format=jbig2dec_format_png;
return 0;
}
#endif
/* default to pbm */
params->output_format=jbig2dec_format_pbm;
 
return 0;
}
 
static int
parse_options(int argc, char *argv[], jbig2dec_params_t *params)
{
static struct option long_options[] = {
{"version", 0, NULL, 'V'},
{"help", 0, NULL, 'h'},
{"quiet", 0, NULL, 'q'},
{"verbose", 2, NULL, 'v'},
{"dump", 0, NULL, 'd'},
{"hash", 0, NULL, 'm'},
{"output", 1, NULL, 'o'},
{"format", 1, NULL, 't'},
{NULL, 0, NULL, 0}
};
int option_idx = 1;
int option;
 
while (1) {
option = getopt_long(argc, argv,
"Vh?qvdo:t:", long_options, &option_idx);
if (option == -1) break;
 
switch (option) {
case 0: /* unknown long option */
if (!params->verbose) fprintf(stdout,
"unrecognized option: --%s\n",
long_options[option_idx].name);
break;
case 'q':
params->verbose = 0;
break;
case 'v':
if (optarg) params->verbose = atoi(optarg);
else params->verbose = 2;
break;
case 'h':
case '?':
params->mode = usage;
break;
case 'V':
/* the GNU Coding Standards suggest --version
should override all other options */
print_version();
exit(0);
break;
case 'd':
params->mode=dump;
break;
case 'm':
params->hash = 1;
break;
case 'o':
params->output_file = strdup(optarg);
break;
case 't':
set_output_format(params, optarg);
break;
default:
if (!params->verbose) fprintf(stdout,
"unrecognized option: -%c\n", option);
break;
}
}
return (optind);
}
 
static int
print_version (void)
{
fprintf(stdout, "%s %s\n", PACKAGE, VERSION);
return 0;
}
 
static int
print_usage (void)
{
fprintf(stderr,
"Usage: jbig2dec [options] <file.jbig2>\n"
" or jbig2dec [options] <global_stream> <page_stream>\n"
"\n"
" When invoked with a single file, it attempts to parse it as\n"
" a normal jbig2 file. Invoked with two files, it treats the\n"
" first as the global segments, and the second as the segment\n"
" stream for a particular page. This is useful for examining\n"
" embedded streams.\n"
"\n"
" available options:\n"
" -h --help this usage summary\n"
" -q --quiet suppress diagnostic output\n"
" -v --verbose set the verbosity level\n"
" -d --dump print the structure of the jbig2 file\n"
" rather than explicitly decoding\n"
" --version program name and version information\n"
" --hash print a hash of the decoded document\n"
" -o <file> send decoded output to <file>\n"
" Defaults to the the input with a different\n"
" extension. Pass '-' for stdout.\n"
" -t <type> force a particular output file format\n"
#ifdef HAVE_LIBPNG
" supported options are 'png' and 'pbm'\n"
#else
" the only supported option is 'pbm'\n"
#endif
"\n"
);
 
return 1;
}
 
static int
error_callback(void *error_callback_data, const char *buf, Jbig2Severity severity,
int32_t seg_idx)
{
const jbig2dec_params_t *params = error_callback_data;
char *type;
char segment[22];
 
switch (severity) {
case JBIG2_SEVERITY_DEBUG:
if (params->verbose < 3) return 0;
type = "DEBUG"; break;;
case JBIG2_SEVERITY_INFO:
if (params->verbose < 2) return 0;
type = "info"; break;;
case JBIG2_SEVERITY_WARNING:
if (params->verbose < 1) return 0;
type = "WARNING"; break;;
case JBIG2_SEVERITY_FATAL: type = "FATAL ERROR"; break;;
default: type = "unknown message"; break;;
}
if (seg_idx == -1) segment[0] = '\0';
else snprintf(segment, sizeof(segment), "(segment 0x%02x)", seg_idx);
 
fprintf(stderr, "jbig2dec %s %s %s\n", type, buf, segment);
 
return 0;
}
 
static char *
make_output_filename(const char *input_filename, const char *extension)
{
char *output_filename;
const char *c, *e;
int len;
 
if (extension == NULL) {
fprintf(stderr, "make_output_filename called with no extension!\n");
exit (1);
}
 
if (input_filename == NULL)
c = "out";
else {
/* strip any leading path */
c = strrchr(input_filename, '/'); /* *nix */
if (c == NULL)
c = strrchr(input_filename, '\\'); /* win32/dos */
if (c != NULL)
c++; /* skip the path separator */
else
c = input_filename; /* no leading path */
}
 
/* make sure we haven't just stripped the last character */
if (*c == '\0')
c = "out";
 
/* strip the extension */
len = strlen(c);
e = strrchr(c, '.');
if (e != NULL)
len -= strlen(e);
 
/* allocate enough space for the base + ext */
output_filename = malloc(len + strlen(extension) + 1);
if (output_filename == NULL) {
fprintf(stderr, "couldn't allocate memory for output_filename\n");
exit (1);
}
 
strncpy(output_filename, c, len);
strncpy(output_filename + len, extension, strlen(extension));
*(output_filename + len + strlen(extension)) = '\0';
 
/* return the new string */
return (output_filename);
}
 
static int
write_page_image(jbig2dec_params_t *params, Jbig2Image *image)
{
if (!strncmp(params->output_file, "-", 2))
{
switch (params->output_format) {
#ifdef HAVE_LIBPNG
case jbig2dec_format_png:
jbig2_image_write_png(image, stdout);
break;
#endif
case jbig2dec_format_pbm:
jbig2_image_write_pbm(image, stdout);
break;
default:
fprintf(stderr, "unsupported output format.\n");
return 1;
}
}
else
{
if (params->verbose > 1)
fprintf(stderr, "saving decoded page as '%s'\n", params->output_file);
switch (params->output_format) {
#ifdef HAVE_LIBPNG
case jbig2dec_format_png:
jbig2_image_write_png_file(image, params->output_file);
break;
#endif
case jbig2dec_format_pbm:
jbig2_image_write_pbm_file(image, params->output_file);
break;
default:
fprintf(stderr, "unsupported output format.\n");
return 1;
}
}
 
return 0;
}
 
static int
write_document_hash(jbig2dec_params_t *params)
{
FILE *out;
 
if (!strncmp(params->output_file, "-", 2)) {
out = stderr;
} else {
out = stdout;
}
 
fprintf(out, "Hash of decoded document: ");
hash_print(params, out);
fprintf(out, "\n");
 
return 0;
}
 
int
main (int argc, char **argv)
{
FILE *f = NULL, *f_page = NULL;
Jbig2Ctx *ctx;
uint8_t buf[4096];
jbig2dec_params_t params;
int filearg;
 
/* set defaults */
params.mode = render;
params.verbose = 1;
params.hash = 0;
params.output_file = NULL;
params.output_format = jbig2dec_format_none;
 
filearg = parse_options(argc, argv, &params);
 
if (params.hash) hash_init(&params);
 
switch (params.mode) {
case usage:
print_usage();
exit (0);
break;
case dump:
fprintf(stderr, "Sorry, segment dump not yet implemented\n");
break;
case render:
 
if ((argc - filearg) == 1)
/* only one argument--open as a jbig2 file */
{
char *fn = argv[filearg];
 
f = fopen(fn, "rb");
if (f == NULL)
{
fprintf(stderr, "error opening %s\n", fn);
return 1;
}
}
else if ((argc - filearg) == 2)
/* two arguments open as separate global and page streams */
{
char *fn = argv[filearg];
char *fn_page = argv[filearg+1];
 
f = fopen(fn, "rb");
if (f == NULL)
{
fprintf(stderr, "error opening %s\n", fn);
return 1;
}
 
f_page = fopen(fn_page, "rb");
if (f_page == NULL)
{
fprintf(stderr, "error opening %s\n", fn_page);
return 1;
}
}
else
/* any other number of arguments */
return print_usage();
 
ctx = jbig2_ctx_new(NULL, f_page != NULL ? JBIG2_OPTIONS_EMBEDDED : 0,
NULL,
error_callback, &params);
 
/* pull the whole file/global stream into memory */
for (;;)
{
int n_bytes = fread(buf, 1, sizeof(buf), f);
if (n_bytes <= 0)
break;
if (jbig2_data_in(ctx, buf, n_bytes))
break;
}
fclose(f);
 
/* if there's a local page stream read that in its entirety */
if (f_page != NULL)
{
Jbig2GlobalCtx *global_ctx = jbig2_make_global_ctx(ctx);
ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, global_ctx,
error_callback, &params);
for (;;)
{
int n_bytes = fread(buf, 1, sizeof(buf), f_page);
if (n_bytes <= 0)
break;
if (jbig2_data_in(ctx, buf, n_bytes))
break;
}
fclose(f_page);
jbig2_global_ctx_free(global_ctx);
}
 
/* retrieve and output the returned pages */
{
Jbig2Image *image;
 
/* work around broken CVision embedded streams */
if (f_page != NULL)
jbig2_complete_page(ctx);
 
if (params.output_file == NULL)
{
#ifdef HAVE_LIBPNG
params.output_file = make_output_filename(argv[filearg], ".png");
params.output_format = jbig2dec_format_png;
#else
params.output_file = make_output_filename(argv[filearg], ".pbm");
params.output_format = jbig2dec_format_pbm;
#endif
} else {
int len = strlen(params.output_file);
if ((len >= 3) && (params.output_format == jbig2dec_format_none))
/* try to set the output type by the given extension */
set_output_format(&params, params.output_file + len - 3);
}
 
/* retrieve and write out all the completed pages */
while ((image = jbig2_page_out(ctx)) != NULL) {
write_page_image(&params, image);
if (params.hash) hash_image(&params, image);
jbig2_release_page(ctx, image);
}
if (params.hash) write_document_hash(&params);
}
 
jbig2_ctx_free(ctx);
 
} /* end params.mode switch */
 
if (params.output_file) free(params.output_file);
if (params.hash) hash_free(&params);
 
/* fin */
return 0;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/memcmp.c
0,0 → 1,49
/*
jbig2dec
 
Copyright (C) 2001-2005 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
 
#include <stddef.h>
 
/* replacement for broken memcmp() */
 
/*
* compares two byte strings 'a' and 'b', both assumed to be 'len' bytes long
* returns zero if the two strings are identical, otherwise returns -1 or 1
* depending on the relative magnitude of the first differing elements,
* considered as unsigned chars
*/
 
int memcmp(const void *b1, const void *b2, size_t len)
{
unsigned char *a, *b;
size_t i;
 
a = (unsigned char *)b1;
b = (unsigned char *)b2;
for(i = 0; i < len; i++) {
if (*a != *b) {
/* strings differ */
return (*a < *b) ? -1 : 1;
}
a++;
b++;
}
 
/* strings match */
return 0;
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/os_types.h
0,0 → 1,51
/*
jbig2dec
 
Copyright (C) 2003 Artifex Software, Inc.
 
This software is distributed under license and may not
be copied, modified or distributed except as expressly
authorized under the terms of the license contained in
the file LICENSE in this distribution.
 
For further licensing information refer to http://artifex.com/ or
contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
*/
 
/*
indirection layer for build and platform-specific definitions
 
in general, this header should ensure that the stdint types are
available, and that any optional compile flags are defined if
the build system doesn't pass them directly.
*/
 
#ifndef _JBIG2_OS_TYPES_H
#define _JBIG2_OS_TYPES_H
 
#if defined(__CYGWIN__) && !defined(HAVE_STDINT_H)
# include <sys/types.h>
# if defined(OLD_CYGWIN_SYS_TYPES)
/*
* Old versions of Cygwin have no stdint.h but define "MS types". Some of
* them conflict with a standard type emulation provided by config_types.h
* so we do a fixup here.
*/
typedef u_int8_t uint8_t;
typedef u_int16_t uint16_t;
typedef u_int32_t uint32_t;
#endif
#elif defined(HAVE_CONFIG_H)
# include "config_types.h"
#elif defined(_WIN32) || defined(__WIN32__)
# include "config_win32.h"
#endif
 
#if defined(HAVE_STDINT_H) || defined(__MACOS__)
# include <stdint.h>
#elif defined(__VMS)
# include <inttypes.h>
#endif
 
#endif /* _JBIG2_OS_TYPES_H */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/sha1.c
0,0 → 1,375
/*
SHA-1 in C
By Steve Reid <sreid@sea-to-sky.net>
100% Public Domain
 
-----------------
Modified 7/98
By James H. Brown <jbrown@burgoyne.com>
Still 100% Public Domain
 
Corrected a problem which generated improper hash values on 16 bit machines
Routine SHA1Update changed from
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
len)
to
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
long len)
 
The 'len' parameter was declared an int which works fine on 32 bit machines.
However, on 16 bit machines an int is too small for the shifts being done
against
it. This caused the hash function to generate incorrect values if len was
greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
 
Since the file IO in main() reads 16K at a time, any file 8K or larger would
be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
"a"s).
 
I also changed the declaration of variables i & j in SHA1Update to
unsigned long from unsigned int for the same reason.
 
These changes should make no difference to any 32 bit implementations since
an
int and a long are the same size in those environments.
 
--
I also corrected a few compiler warnings generated by Borland C.
1. Added #include <process.h> for exit() prototype
2. Removed unused variable 'j' in SHA1Final
3. Changed exit(0) to return(0) at end of main.
 
ALL changes I made can be located by searching for comments containing 'JHB'
-----------------
Modified 8/98
By Steve Reid <sreid@sea-to-sky.net>
Still 100% public domain
 
1- Removed #include <process.h> and used return() instead of exit()
2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
 
-----------------
Modified 4/01
By Saul Kravitz <Saul.Kravitz@celera.com>
Still 100% PD
Modified to run on Compaq Alpha hardware.
 
-----------------
Modified 07/2002
By Ralph Giles <giles@ghostscript.com>
Still 100% public domain
modified for use with stdint types, autoconf
code cleanup, removed attribution comments
switched SHA1Final() argument order for consistency
use SHA1_ prefix for public api
move public api to sha1.h
*/
 
/*
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
 
/* #define SHA1HANDSOFF */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
 
#include <stdio.h>
#include <string.h>
 
#include "os_types.h"
#include "sha1.h"
 
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
 
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
 
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
/* FIXME: can we do this in an endian-proof way? */
#ifdef WORDS_BIGENDIAN
#define blk0(i) block->l[i]
#else
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
 
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
 
 
#ifdef VERBOSE /* SAK */
void SHAPrintContext(SHA1_CTX *context, char *msg){
printf("%s (%d,%d) %x %x %x %x %x\n",
msg,
context->count[0], context->count[1],
context->state[0],
context->state[1],
context->state[2],
context->state[3],
context->state[4]);
}
#endif /* VERBOSE */
 
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
{
uint32_t a, b, c, d, e;
typedef union {
uint8_t c[64];
uint32_t l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
 
#ifdef SHA1HANDSOFF
static uint8_t workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
 
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
 
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
 
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
 
/* Wipe variables */
a = b = c = d = e = 0;
}
 
 
/* SHA1Init - Initialize new context */
void SHA1_Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
 
 
/* Run your data through this. */
void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
{
size_t i, j;
 
#ifdef VERBOSE
SHAPrintContext(context, "before");
#endif
 
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1_Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1_Transform(context->state, data + i);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
 
#ifdef VERBOSE
SHAPrintContext(context, "after ");
#endif
}
 
 
/* Add padding and return the message digest. */
void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
{
uint32_t i;
uint8_t finalcount[8];
 
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1_Update(context, (uint8_t *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1_Update(context, (uint8_t *)"\0", 1);
}
SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
digest[i] = (uint8_t)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
 
/* Wipe variables */
i = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(finalcount, 0, 8); /* SWR */
 
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
SHA1_Transform(context->state, context->buffer);
#endif
}
 
/*************************************************************/
 
#if 0
int main(int argc, char** argv)
{
int i, j;
SHA1_CTX context;
unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384];
FILE* file;
 
if (argc > 2) {
puts("Public domain SHA-1 implementation - by Steve Reid <sreid@sea-to-sky.net>");
puts("Modified for 16 bit environments 7/98 - by James H. Brown <jbrown@burgoyne.com>"); /* JHB */
puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
return(0);
}
if (argc < 2) {
file = stdin;
}
else {
if (!(file = fopen(argv[1], "rb"))) {
fputs("Unable to open file.", stderr);
return(-1);
}
}
SHA1_Init(&context);
while (!feof(file)) { /* note: what if ferror(file) */
i = fread(buffer, 1, 16384, file);
SHA1_Update(&context, buffer, i);
}
SHA1_Final(&context, digest);
fclose(file);
for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
for (j = 0; j < 4; j++) {
printf("%02X", digest[i*4+j]);
}
putchar(' ');
}
putchar('\n');
return(0); /* JHB */
}
#endif
 
/* self test */
 
#ifdef TEST
 
static char *test_data[] = {
"abc",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"A million repetitions of 'a'"};
static char *test_results[] = {
"A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
"84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
"34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"};
 
 
void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output)
{
int i,j;
char *c = output;
 
for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
for (j = 0; j < 4; j++) {
sprintf(c,"%02X", digest[i*4+j]);
c += 2;
}
sprintf(c, " ");
c += 1;
}
*(c - 1) = '\0';
}
 
int main(int argc, char** argv)
{
int k;
SHA1_CTX context;
uint8_t digest[20];
char output[80];
 
fprintf(stdout, "verifying SHA-1 implementation... ");
 
for (k = 0; k < 2; k++){
SHA1_Init(&context);
SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k]));
SHA1_Final(&context, digest);
digest_to_hex(digest, output);
 
if (strcmp(output, test_results[k])) {
fprintf(stdout, "FAIL\n");
fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]);
fprintf(stderr,"\t%s returned\n", output);
fprintf(stderr,"\t%s is correct\n", test_results[k]);
return (1);
}
}
/* million 'a' vector we feed separately */
SHA1_Init(&context);
for (k = 0; k < 1000000; k++)
SHA1_Update(&context, (uint8_t*)"a", 1);
SHA1_Final(&context, digest);
digest_to_hex(digest, output);
if (strcmp(output, test_results[2])) {
fprintf(stdout, "FAIL\n");
fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
fprintf(stderr,"\t%s returned\n", output);
fprintf(stderr,"\t%s is correct\n", test_results[2]);
return (1);
}
 
/* success */
fprintf(stdout, "ok\n");
return(0);
}
#endif /* TEST */
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/contrib/sdk/sources/libjbig2dec/sha1.h
0,0 → 1,27
/* public api for steve reid's public domain SHA-1 implementation */
/* this file is in the public domain */
 
#ifndef __SHA1_H
#define __SHA1_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
typedef struct {
uint32_t state[5];
uint32_t count[2];
uint8_t buffer[64];
} SHA1_CTX;
 
#define SHA1_DIGEST_SIZE 20
 
void SHA1_Init(SHA1_CTX* context);
void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len);
void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]);
 
#ifdef __cplusplus
}
#endif
 
#endif /* __SHA1_H */
Property changes:
Added: svn:executable
+*
\ No newline at end of property