Author: ken
Date: 2010-12-18 11:19:22 -0700 (Sat, 18 Dec 2010)
New Revision: 2261
Added:
trunk/ghostscript/ghostscript-9.00-security_fixes-1.patch
trunk/ghostscript/ghostscript-9.00-system_jasper-1.patch
Log:
Fixes for ghostscript-9.00
Added: trunk/ghostscript/ghostscript-9.00-security_fixes-1.patch
===================================================================
--- trunk/ghostscript/ghostscript-9.00-security_fixes-1.patch
(rev 0)
+++ trunk/ghostscript/ghostscript-9.00-security_fixes-1.patch 2010-12-18
18:19:22 UTC (rev 2261)
@@ -0,0 +1,1053 @@
+Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
+Date: 2010-12-18
+Initial Package Version: 9.00
+Upstream Status: unknown
+Origin: debian and fedora
+Description: First part is a fix for CVE-2009-4270 (supposedly fixed in 8.71)
+found at debian, remainder are two fixes for null dereferences in the included
+jbig2dec (note that ghostscript _is_ the upstream for jbig2dec).
+
+diff -Naur ghostscript-9.00.orig//base/gsmisc.c ghostscript-9.00/base/gsmisc.c
+--- ghostscript-9.00.orig//base/gsmisc.c 2010-05-06 17:04:27.000000000
+0100
++++ ghostscript-9.00/base/gsmisc.c 2010-12-18 18:07:08.000000000 +0000
+@@ -260,7 +260,7 @@
+ va_list ap;
+
+ va_start(ap, fmt);
+- vsprintf(msg, fmt, ap);
++ vsnprintf(msg, sizeof(msg), fmt, ap);
+ msg[sizeof(msg) - 1] = 0;
+ va_end(ap);
+
+diff -Naur ghostscript-9.00.orig//jbig2dec/jbig2_image.c
ghostscript-9.00/jbig2dec/jbig2_image.c
+--- ghostscript-9.00.orig//jbig2dec/jbig2_image.c 2010-07-20
09:23:05.000000000 +0100
++++ ghostscript-9.00/jbig2dec/jbig2_image.c 2010-12-18 18:08:55.000000000
+0000
+@@ -60,15 +60,18 @@
+ /* clone an image pointer by bumping its reference count */
+ Jbig2Image* jbig2_image_clone(Jbig2Ctx *ctx, Jbig2Image *image)
+ {
+- image->refcount++;
++ if (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);
++ if (image) {
++ image->refcount--;
++ if (!image->refcount) jbig2_image_free(ctx, image);
++ }
+ }
+
+ /* free a Jbig2Image structure and its associated memory */
+diff -Naur ghostscript-9.00.orig//jbig2dec/jbig2_symbol_dict.c
ghostscript-9.00/jbig2dec/jbig2_symbol_dict.c
+--- ghostscript-9.00.orig//jbig2dec/jbig2_symbol_dict.c 2010-07-20
10:46:34.000000000 +0100
++++ ghostscript-9.00/jbig2dec/jbig2_symbol_dict.c 2010-12-18
18:07:37.000000000 +0000
+@@ -364,6 +364,11 @@
+ memcpy(region_params.gbat, params->sdat, sdat_bytes);
+
+ image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
++ if (image == NULL) {
++ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++ "failed to allocate image storage");
++ return NULL;
++ }
+
+ code = jbig2_decode_generic_region(ctx, segment,
®ion_params,
+ as, image, GB_stats);
+@@ -514,6 +519,11 @@
+ ID, RDX, RDY);
+
+ image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
++ if (image == NULL) {
++ jbig2_error(ctx, JBIG2_SEVERITY_FATAL,
segment->number,
++ "failed to allocate image storage");
++ return NULL;
++ }
+
+ /* Table 18 */
+ rparams.GRTEMPLATE = params->SDRTEMPLATE;
+@@ -632,6 +642,16 @@
+ for (j = HCFIRSTSYM; j < NSYMSDECODED; j++) {
+ Jbig2Image *glyph;
+ glyph = jbig2_image_new(ctx, SDNEWSYMWIDTHS[j], HCHEIGHT);
++ if (glyph == NULL) {
++ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++ "error allocating image storage for glyph");
++ while (--j >= HCFIRSTSYM) {
++ jbig2_image_release(ctx, SDNEWSYMS->glyphs[j]);
++ SDNEWSYMS->glyphs[j] = NULL;
++ }
++ jbig2_image_release(ctx, image);
++ return NULL;
++ }
+ jbig2_image_compose(ctx, glyph, image,
+ -x, 0, JBIG2_COMPOSE_REPLACE);
+ x += SDNEWSYMWIDTHS[j];
+diff -Naur ghostscript-9.00.orig//jbig2dec/jbig2_symbol_dict.c.orig
ghostscript-9.00/jbig2dec/jbig2_symbol_dict.c.orig
+--- ghostscript-9.00.orig//jbig2dec/jbig2_symbol_dict.c.orig 1970-01-01
01:00:00.000000000 +0100
++++ ghostscript-9.00/jbig2dec/jbig2_symbol_dict.c.orig 2010-07-20
10:46:34.000000000 +0100
+@@ -0,0 +1,959 @@
++/*
++ 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 = jbig2_new(ctx, Jbig2SymbolDict, 1);
++ if (new != NULL) {
++ new->glyphs = jbig2_new(ctx, Jbig2Image*, n_symbols);
++ 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_new(ctx, 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_new(ctx, uint32_t, 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,
®ion_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_new(ctx, 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_new(ctx, Jbig2TextRegionParams, 1);
++ 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 = exflag ? params->SDNUMEXSYMS : 0;
++ else
++ code = jbig2_arith_int_decode(IAEX, as, &exrunlength);
++ if (exflag && 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;
++ int table_index = 0;
++ const Jbig2HuffmanParams *huffman_params;
++
++ 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 */
++ huffman_params = jbig2_find_table(ctx, segment, table_index);
++ if (huffman_params == NULL) {
++ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++ "Custom DH huffman table not found (%d)", table_index);
++ }
++ params.SDHUFFDH = jbig2_build_huffman_table(ctx, huffman_params);
++ ++table_index;
++ break;
++ /* FIXME: this function leaks memory when error happens.
++ i.e. not calling jbig2_release_huffman_table() */
++ 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 */
++ huffman_params = jbig2_find_table(ctx, segment, table_index);
++ if (huffman_params == NULL) {
++ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++ "Custom DW huffman table not found (%d)", table_index);
++ }
++ params.SDHUFFDW = jbig2_build_huffman_table(ctx, huffman_params);
++ ++table_index;
++ break;
++ 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 */
++ huffman_params = jbig2_find_table(ctx, segment, table_index);
++ if (huffman_params == NULL) {
++ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++ "Custom BMSIZE huffman table not found (%d)", table_index);
++ }
++ params.SDHUFFBMSIZE = jbig2_build_huffman_table(ctx, huffman_params);
++ ++table_index;
++ } else {
++ /* Table B.1 */
++ params.SDHUFFBMSIZE = jbig2_build_huffman_table(ctx,
++ &jbig2_huffman_params_A);
++ }
++ if (flags & 0x0080) {
++ /* Custom table from referred segment */
++ huffman_params = jbig2_find_table(ctx, segment, table_index);
++ if (huffman_params == NULL) {
++ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++ "Custom REFAGG huffman table not found (%d)", table_index);
++ }
++ params.SDHUFFAGGINST = jbig2_build_huffman_table(ctx, huffman_params);
++ ++table_index;
++ } 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_new(ctx, Jbig2ArithCx, stats_size);
++ memset(GB_stats, 0, stats_size);
++ if (params.SDREFAGG) {
++ stats_size = params.SDRTEMPLATE ? 1 << 10 : 1 << 13;
++ GR_stats = jbig2_new(ctx, Jbig2ArithCx, 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,
++ ¶ms,
++ 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");
++}
Added: trunk/ghostscript/ghostscript-9.00-system_jasper-1.patch
===================================================================
--- trunk/ghostscript/ghostscript-9.00-system_jasper-1.patch
(rev 0)
+++ trunk/ghostscript/ghostscript-9.00-system_jasper-1.patch 2010-12-18
18:19:22 UTC (rev 2261)
@@ -0,0 +1 @@
+link ghostscript-8.70-system_jasper-1.patch
\ No newline at end of file
Property changes on: trunk/ghostscript/ghostscript-9.00-system_jasper-1.patch
___________________________________________________________________
Added: svn:special
+ *
--
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page