|
Packit |
3f21c4 |
/* Copyright (C) 2001-2012 Artifex Software, Inc.
|
|
Packit |
3f21c4 |
All Rights Reserved.
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
This software is provided AS-IS with no warranty, either express or
|
|
Packit |
3f21c4 |
implied.
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
This software is distributed under license and may not be copied,
|
|
Packit |
3f21c4 |
modified or distributed except as expressly authorized under the terms
|
|
Packit |
3f21c4 |
of the license contained in the file LICENSE in this distribution.
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
Refer to licensing information at http://www.artifex.com or contact
|
|
Packit |
3f21c4 |
Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
|
|
Packit |
3f21c4 |
CA 94903, U.S.A., +1(415)492-9861, for further information.
|
|
Packit |
3f21c4 |
*/
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/*
|
|
Packit |
3f21c4 |
jbig2dec
|
|
Packit |
3f21c4 |
*/
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
3f21c4 |
#include "config.h"
|
|
Packit |
3f21c4 |
#endif
|
|
Packit |
3f21c4 |
#include "os_types.h"
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
#include <stdio.h>
|
|
Packit |
3f21c4 |
#include <stdlib.h>
|
|
Packit |
3f21c4 |
#include <string.h> /* memcpy() */
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
#include "jbig2.h"
|
|
Packit |
3f21c4 |
#include "jbig2_priv.h"
|
|
Packit |
3f21c4 |
#include "jbig2_image.h"
|
|
Packit |
3f21c4 |
|
|
Packit Service |
9f36f9 |
#if !defined (UINT32_MAX)
|
|
Packit Service |
9f36f9 |
#define UINT32_MAX 0xffffffffu
|
|
Packit Service |
9f36f9 |
#endif
|
|
Packit Service |
9f36f9 |
|
|
Packit |
3f21c4 |
/* allocate a Jbig2Image structure and its associated bitmap */
|
|
Packit |
3f21c4 |
Jbig2Image *
|
|
Packit |
3f21c4 |
jbig2_image_new(Jbig2Ctx *ctx, uint32_t width, uint32_t height)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
Jbig2Image *image;
|
|
Packit |
3f21c4 |
uint32_t stride;
|
|
Packit |
3f21c4 |
int64_t check;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
if (width == 0 || height == 0) {
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
|
|
Packit |
3f21c4 |
"zero width (%d) or height (%d) in jbig2_image_new",
|
|
Packit |
3f21c4 |
width, height);
|
|
Packit |
3f21c4 |
return NULL;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
image = jbig2_new(ctx, Jbig2Image, 1);
|
|
Packit |
3f21c4 |
if (image == NULL) {
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "could not allocate image structure in jbig2_image_new");
|
|
Packit |
3f21c4 |
return NULL;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
stride = ((width - 1) >> 3) + 1; /* generate a byte-aligned stride */
|
|
Packit |
3f21c4 |
/* check for integer multiplication overflow */
|
|
Packit |
3f21c4 |
check = ((int64_t) stride) * ((int64_t) height);
|
|
Packit |
3f21c4 |
if (check != (int)check) {
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "integer multiplication overflow from stride(%d)*height(%d)", stride, height);
|
|
Packit |
3f21c4 |
jbig2_free(ctx->allocator, image);
|
|
Packit |
3f21c4 |
return NULL;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
/* Add 1 to accept runs that exceed image width and clamped to width+1 */
|
|
Packit |
3f21c4 |
image->data = jbig2_new(ctx, uint8_t, (int)check + 1);
|
|
Packit |
3f21c4 |
if (image->data == NULL) {
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "could not allocate image data buffer! [stride(%d)*height(%d) bytes]", stride, height);
|
|
Packit |
3f21c4 |
jbig2_free(ctx->allocator, image);
|
|
Packit |
3f21c4 |
return NULL;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
image->width = width;
|
|
Packit |
3f21c4 |
image->height = height;
|
|
Packit |
3f21c4 |
image->stride = stride;
|
|
Packit |
3f21c4 |
image->refcount = 1;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
return image;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* clone an image pointer by bumping its reference count */
|
|
Packit |
3f21c4 |
Jbig2Image *
|
|
Packit |
3f21c4 |
jbig2_image_clone(Jbig2Ctx *ctx, Jbig2Image *image)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
if (image)
|
|
Packit |
3f21c4 |
image->refcount++;
|
|
Packit |
3f21c4 |
return image;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* release an image pointer, freeing it it appropriate */
|
|
Packit |
3f21c4 |
void
|
|
Packit |
3f21c4 |
jbig2_image_release(Jbig2Ctx *ctx, Jbig2Image *image)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
if (image == NULL)
|
|
Packit |
3f21c4 |
return;
|
|
Packit |
3f21c4 |
image->refcount--;
|
|
Packit |
3f21c4 |
if (!image->refcount)
|
|
Packit |
3f21c4 |
jbig2_image_free(ctx, image);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* free a Jbig2Image structure and its associated memory */
|
|
Packit |
3f21c4 |
void
|
|
Packit |
3f21c4 |
jbig2_image_free(Jbig2Ctx *ctx, Jbig2Image *image)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
if (image)
|
|
Packit |
3f21c4 |
jbig2_free(ctx->allocator, image->data);
|
|
Packit |
3f21c4 |
jbig2_free(ctx->allocator, image);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* resize a Jbig2Image */
|
|
Packit |
3f21c4 |
Jbig2Image *
|
|
Packit |
3f21c4 |
jbig2_image_resize(Jbig2Ctx *ctx, Jbig2Image *image, uint32_t width, uint32_t height)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
if (width == image->width) {
|
|
Packit |
3f21c4 |
/* check for integer multiplication overflow */
|
|
Packit |
3f21c4 |
int64_t check = ((int64_t) image->stride) * ((int64_t) height);
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
if (check != (int)check) {
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "integer multiplication overflow during resize stride(%d)*height(%d)", image->stride, height);
|
|
Packit |
3f21c4 |
return NULL;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
/* use the same stride, just change the length */
|
|
Packit |
3f21c4 |
image->data = jbig2_renew(ctx, image->data, uint8_t, (int)check);
|
|
Packit |
3f21c4 |
if (image->data == NULL) {
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "could not resize image buffer!");
|
|
Packit |
3f21c4 |
return NULL;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
if (height > image->height) {
|
|
Packit |
3f21c4 |
memset(image->data + image->height * image->stride, 0, (height - image->height) * image->stride);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
image->height = height;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
} else {
|
|
Packit |
3f21c4 |
/* we must allocate a new image buffer and copy */
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "jbig2_image_resize called with a different width (NYI)");
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
return NULL;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* composite one jbig2_image onto another
|
|
Packit |
3f21c4 |
slow but general version */
|
|
Packit |
3f21c4 |
static int
|
|
Packit |
3f21c4 |
jbig2_image_compose_unopt(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src, int x, int y, Jbig2ComposeOp op)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
uint32_t i, j;
|
|
Packit |
3f21c4 |
uint32_t sw = src->width;
|
|
Packit |
3f21c4 |
uint32_t sh = src->height;
|
|
Packit |
3f21c4 |
uint32_t sx = 0;
|
|
Packit |
3f21c4 |
uint32_t sy = 0;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* clip to the dst image boundaries */
|
|
Packit |
3f21c4 |
if (x < 0) {
|
|
Packit |
3f21c4 |
sx += -x;
|
|
Packit |
3f21c4 |
if (sw < (uint32_t)-x)
|
|
Packit |
3f21c4 |
sw = 0;
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
sw -= -x;
|
|
Packit |
3f21c4 |
x = 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
if (y < 0) {
|
|
Packit |
3f21c4 |
sy += -y;
|
|
Packit |
3f21c4 |
if (sh < (uint32_t)-y)
|
|
Packit |
3f21c4 |
sh = 0;
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
sh -= -y;
|
|
Packit |
3f21c4 |
y = 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
if ((uint32_t)x + sw >= dst->width) {
|
|
Packit |
3f21c4 |
if (dst->width >= (uint32_t)x)
|
|
Packit |
3f21c4 |
sw = dst->width - x;
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
sw = 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
if ((uint32_t)y + sh >= dst->height) {
|
|
Packit |
3f21c4 |
if (dst->height >= (uint32_t)y)
|
|
Packit |
3f21c4 |
sh = dst->height - y;
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
sh = 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
switch (op) {
|
|
Packit |
3f21c4 |
case JBIG2_COMPOSE_OR:
|
|
Packit |
3f21c4 |
for (j = 0; j < sh; j++) {
|
|
Packit |
3f21c4 |
for (i = 0; i < sw; i++) {
|
|
Packit |
3f21c4 |
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));
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
break;
|
|
Packit |
3f21c4 |
case JBIG2_COMPOSE_AND:
|
|
Packit |
3f21c4 |
for (j = 0; j < sh; j++) {
|
|
Packit |
3f21c4 |
for (i = 0; i < sw; i++) {
|
|
Packit |
3f21c4 |
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));
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
break;
|
|
Packit |
3f21c4 |
case JBIG2_COMPOSE_XOR:
|
|
Packit |
3f21c4 |
for (j = 0; j < sh; j++) {
|
|
Packit |
3f21c4 |
for (i = 0; i < sw; i++) {
|
|
Packit |
3f21c4 |
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));
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
break;
|
|
Packit |
3f21c4 |
case JBIG2_COMPOSE_XNOR:
|
|
Packit |
3f21c4 |
for (j = 0; j < sh; j++) {
|
|
Packit |
3f21c4 |
for (i = 0; i < sw; i++) {
|
|
Packit |
3f21c4 |
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)));
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
break;
|
|
Packit |
3f21c4 |
case JBIG2_COMPOSE_REPLACE:
|
|
Packit |
3f21c4 |
for (j = 0; j < sh; j++) {
|
|
Packit |
3f21c4 |
for (i = 0; i < sw; i++) {
|
|
Packit |
3f21c4 |
jbig2_image_set_pixel(dst, i + x, j + y, jbig2_image_get_pixel(src, i + sx, j + sy));
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
break;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* composite one jbig2_image onto another */
|
|
Packit |
3f21c4 |
int
|
|
Packit |
3f21c4 |
jbig2_image_compose(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src, int x, int y, Jbig2ComposeOp op)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
uint32_t i, j;
|
|
Packit |
3f21c4 |
uint32_t w, h;
|
|
Packit |
3f21c4 |
uint32_t leftbyte, rightbyte;
|
|
Packit |
3f21c4 |
uint32_t shift;
|
|
Packit |
3f21c4 |
uint8_t *s, *ss;
|
|
Packit |
3f21c4 |
uint8_t *d, *dd;
|
|
Packit |
3f21c4 |
uint8_t mask, rightmask;
|
|
Packit |
3f21c4 |
|
|
Packit Service |
9f36f9 |
if ((UINT32_MAX - src->width < (x > 0 ? x : -x)) ||
|
|
Packit Service |
9f36f9 |
(UINT32_MAX - src->height < (y > 0 ? y : -y)))
|
|
Packit Service |
9f36f9 |
{
|
|
Packit Service |
9f36f9 |
#ifdef JBIG2_DEBUG
|
|
Packit Service |
9f36f9 |
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "overflow in compose_image");
|
|
Packit Service |
9f36f9 |
#endif
|
|
Packit Service |
9f36f9 |
return 0;
|
|
Packit Service |
9f36f9 |
}
|
|
Packit Service |
9f36f9 |
|
|
Packit |
3f21c4 |
if (op != JBIG2_COMPOSE_OR) {
|
|
Packit |
3f21c4 |
/* hand off the the general routine */
|
|
Packit |
3f21c4 |
return jbig2_image_compose_unopt(ctx, dst, src, x, y, op);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* clip */
|
|
Packit |
3f21c4 |
w = src->width;
|
|
Packit |
3f21c4 |
h = src->height;
|
|
Packit |
3f21c4 |
ss = src->data;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
if (x < 0) {
|
|
Packit |
3f21c4 |
if (w < (uint32_t)-x)
|
|
Packit |
3f21c4 |
w = 0;
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
w += x;
|
|
Packit |
3f21c4 |
x = 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
if (y < 0) {
|
|
Packit |
3f21c4 |
if (h < (uint32_t)-y)
|
|
Packit |
3f21c4 |
h = 0;
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
h += y;
|
|
Packit |
3f21c4 |
y = 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
w = ((uint32_t)x + w < dst->width) ? w : ((dst->width >= (uint32_t)x) ? dst->width - (uint32_t)x : 0);
|
|
Packit |
3f21c4 |
h = ((uint32_t)y + h < dst->height) ? h : ((dst->height >= (uint32_t)y) ? dst->height - (uint32_t)y : 0);
|
|
Packit |
3f21c4 |
#ifdef JBIG2_DEBUG
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "compositing %dx%d at (%d, %d) after clipping\n", w, h, x, y);
|
|
Packit |
3f21c4 |
#endif
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* check for zero clipping region */
|
|
Packit |
3f21c4 |
if ((w <= 0) || (h <= 0)) {
|
|
Packit |
3f21c4 |
#ifdef JBIG2_DEBUG
|
|
Packit |
3f21c4 |
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "zero clipping region");
|
|
Packit |
3f21c4 |
#endif
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
#if 0
|
|
Packit |
3f21c4 |
/* special case complete/strip replacement */
|
|
Packit |
3f21c4 |
/* disabled because it's only safe to do when the destination
|
|
Packit |
3f21c4 |
buffer is all-blank. */
|
|
Packit |
3f21c4 |
if ((x == 0) && (w == src->width)) {
|
|
Packit |
3f21c4 |
memcpy(dst->data + y * dst->stride, src->data, h * src->stride);
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
#endif
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
leftbyte = (uint32_t)x >> 3;
|
|
Packit |
3f21c4 |
rightbyte = ((uint32_t)x + w - 1) >> 3;
|
|
Packit |
3f21c4 |
shift = x & 7;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* general OR case */
|
|
Packit |
3f21c4 |
s = ss;
|
|
Packit |
3f21c4 |
d = dd = dst->data + y * dst->stride + leftbyte;
|
|
Packit |
3f21c4 |
if (d < dst->data || leftbyte > dst->stride || d - leftbyte + h * dst->stride > dst->data + dst->height * dst->stride ||
|
|
Packit |
3f21c4 |
s - leftbyte + (h - 1) * src->stride + rightbyte > src->data + src->height * src->stride) {
|
|
Packit |
3f21c4 |
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1, "preventing heap overflow in jbig2_image_compose");
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
if (leftbyte == rightbyte) {
|
|
Packit |
3f21c4 |
mask = 0x100 - (0x100 >> w);
|
|
Packit |
3f21c4 |
for (j = 0; j < h; j++) {
|
|
Packit |
3f21c4 |
*d |= (*s & mask) >> shift;
|
|
Packit |
3f21c4 |
d += dst->stride;
|
|
Packit |
3f21c4 |
s += src->stride;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
} else if (shift == 0) {
|
|
Packit |
3f21c4 |
rightmask = (w & 7) ? 0x100 - (1 << (8 - (w & 7))) : 0xFF;
|
|
Packit |
3f21c4 |
for (j = 0; j < h; j++) {
|
|
Packit |
3f21c4 |
for (i = leftbyte; i < rightbyte; i++)
|
|
Packit |
3f21c4 |
*d++ |= *s++;
|
|
Packit |
3f21c4 |
*d |= *s & rightmask;
|
|
Packit |
3f21c4 |
d = (dd += dst->stride);
|
|
Packit |
3f21c4 |
s = (ss += src->stride);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
} else {
|
|
Packit |
3f21c4 |
bool overlap = (((w + 7) >> 3) < ((x + w + 7) >> 3) - (x >> 3));
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
mask = 0x100 - (1 << shift);
|
|
Packit |
3f21c4 |
if (overlap)
|
|
Packit |
3f21c4 |
rightmask = (0x100 - (0x100 >> ((x + w) & 7))) >> (8 - shift);
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
rightmask = 0x100 - (0x100 >> (w & 7));
|
|
Packit |
3f21c4 |
for (j = 0; j < h; j++) {
|
|
Packit |
3f21c4 |
*d++ |= (*s & mask) >> shift;
|
|
Packit |
3f21c4 |
for (i = leftbyte; i < rightbyte - 1; i++) {
|
|
Packit |
3f21c4 |
*d |= ((*s++ & ~mask) << (8 - shift));
|
|
Packit |
3f21c4 |
*d++ |= ((*s & mask) >> shift);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
if (overlap)
|
|
Packit |
3f21c4 |
*d |= (*s & rightmask) << (8 - shift);
|
|
Packit |
3f21c4 |
else
|
|
Packit |
3f21c4 |
*d |= ((s[0] & ~mask) << (8 - shift)) | ((s[1] & rightmask) >> shift);
|
|
Packit |
3f21c4 |
d = (dd += dst->stride);
|
|
Packit |
3f21c4 |
s = (ss += src->stride);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* initialize an image bitmap to a constant value */
|
|
Packit |
3f21c4 |
void
|
|
Packit |
3f21c4 |
jbig2_image_clear(Jbig2Ctx *ctx, Jbig2Image *image, int value)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
const uint8_t fill = value ? 0xFF : 0x00;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
memset(image->data, fill, image->stride * image->height);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* look up a pixel value in an image.
|
|
Packit |
3f21c4 |
returns 0 outside the image frame for the convenience of
|
|
Packit |
3f21c4 |
the template code
|
|
Packit |
3f21c4 |
*/
|
|
Packit |
3f21c4 |
int
|
|
Packit |
3f21c4 |
jbig2_image_get_pixel(Jbig2Image *image, int x, int y)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
const int w = image->width;
|
|
Packit |
3f21c4 |
const int h = image->height;
|
|
Packit |
3f21c4 |
const int byte = (x >> 3) + y * image->stride;
|
|
Packit |
3f21c4 |
const int bit = 7 - (x & 7);
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
if ((x < 0) || (x >= w))
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
if ((y < 0) || (y >= h))
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
return ((image->data[byte] >> bit) & 1);
|
|
Packit |
3f21c4 |
}
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
/* set an individual pixel value in an image */
|
|
Packit |
3f21c4 |
int
|
|
Packit |
3f21c4 |
jbig2_image_set_pixel(Jbig2Image *image, int x, int y, bool value)
|
|
Packit |
3f21c4 |
{
|
|
Packit |
3f21c4 |
const int w = image->width;
|
|
Packit |
3f21c4 |
const int h = image->height;
|
|
Packit |
3f21c4 |
int scratch, mask;
|
|
Packit |
3f21c4 |
int bit, byte;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
if ((x < 0) || (x >= w))
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
if ((y < 0) || (y >= h))
|
|
Packit |
3f21c4 |
return 0;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
byte = (x >> 3) + y * image->stride;
|
|
Packit |
3f21c4 |
bit = 7 - (x & 7);
|
|
Packit |
3f21c4 |
mask = (1 << bit) ^ 0xff;
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
scratch = image->data[byte] & mask;
|
|
Packit |
3f21c4 |
image->data[byte] = scratch | (value << bit);
|
|
Packit |
3f21c4 |
|
|
Packit |
3f21c4 |
return 1;
|
|
Packit |
3f21c4 |
}
|