jbig2_generic.c.svn-base

来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 637 行 · 第 1/2 页

SVN-BASE
637
字号
/*
    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 information on commercial licensing, go to
    http://www.artifex.com/licensing/ or contact
    Artifex Software, Inc.,  101 Lucas Valley Road #110,
    San Rafael, CA  94903, U.S.A., +1(415)492-9861.

    $Id: jbig2_generic.c 465 2008-05-16 23:48:20Z giles $
*/

/**
 * 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 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?