Example #1
0
fz_pixmap *
fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor)
{
    fz_pixmap *tile = NULL;
    int stride, len, i;
    unsigned char *samples = NULL;
    int f = 1<<l2factor;
    int w = (image->w + f-1) >> l2factor;
    int h = (image->h + f-1) >> l2factor;

    fz_var(tile);
    fz_var(samples);

    fz_try(ctx)
    {
        tile = fz_new_pixmap(ctx, image->colorspace, w, h);
        tile->interpolate = image->interpolate;

        stride = (w * image->n * image->bpc + 7) / 8;

        samples = fz_malloc_array(ctx, h, stride);

        len = fz_read(ctx, stm, samples, h * stride);

        /* Pad truncated images */
        if (len < stride * h)
        {
            fz_warn(ctx, "padding truncated image");
            memset(samples + len, 0, stride * h - len);
        }

        /* Invert 1-bit image masks */
        if (image->imagemask)
        {
            /* 0=opaque and 1=transparent so we need to invert */
            unsigned char *p = samples;
            len = h * stride;
            for (i = 0; i < len; i++)
                p[i] = ~p[i];
        }

        fz_unpack_tile(ctx, tile, samples, image->n, image->bpc, stride, indexed);

        fz_free(ctx, samples);
        samples = NULL;

        /* color keyed transparency */
        if (image->usecolorkey && !image->mask)
            fz_mask_color_key(tile, image->n, image->colorkey);

        if (indexed)
        {
            fz_pixmap *conv;
            fz_decode_indexed_tile(ctx, tile, image->decode, (1 << image->bpc) - 1);
            conv = fz_expand_indexed_pixmap(ctx, tile);
            fz_drop_pixmap(ctx, tile);
            tile = conv;
        }
        else
        {
            fz_decode_tile(ctx, tile, image->decode);
        }

        /* pre-blended matte color */
        if (image->usecolorkey && image->mask)
            fz_unblend_masked_tile(ctx, tile, image);
    }
    fz_always(ctx)
    {
        fz_drop_stream(ctx, stm);
    }
    fz_catch(ctx)
    {
        if (tile)
            fz_drop_pixmap(ctx, tile);
        fz_free(ctx, samples);

        fz_rethrow(ctx);
    }

    return tile;
}
Example #2
0
fz_pixmap *
fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image *cimg, fz_irect *subarea, int indexed, int l2factor)
{
	fz_image *image = &cimg->super;
	fz_pixmap *tile = NULL;
	size_t stride, len, i;
	unsigned char *samples = NULL;
	int f = 1<<l2factor;
	int w = image->w;
	int h = image->h;

	if (subarea)
	{
		int bpp = image->bpc * image->n;
		int mask;
		switch (bpp)
		{
		case 1: mask = 8*f; break;
		case 2: mask = 4*f; break;
		case 4: mask = 2*f; break;
		default: mask = (bpp & 7) == 0 ? f : 0; break;
		}
		if (mask != 0)
		{
			subarea->x0 &= ~(mask - 1);
			subarea->x1 = (subarea->x1 + mask - 1) & ~(mask - 1);
		}
		else
		{
			/* Awkward case - mask cannot be a power of 2. */
			mask = bpp*f;
			switch (bpp)
			{
			case 3:
			case 5:
			case 7:
			case 9:
			case 11:
			case 13:
			case 15:
			default:
				mask *= 8;
				break;
			case 6:
			case 10:
			case 14:
				mask *= 4;
				break;
			case 12:
				mask *= 2;
				break;
			}
			subarea->x0 = (subarea->x0 / mask) * mask;
			subarea->x1 = ((subarea->x1 + mask - 1) / mask) * mask;
		}
		subarea->y0 &= ~(f - 1);
		if (subarea->x1 > image->w)
			subarea->x1 = image->w;
		subarea->y1 = (subarea->y1 + f - 1) & ~(f - 1);
		if (subarea->y1 > image->h)
			subarea->y1 = image->h;
		w = (subarea->x1 - subarea->x0);
		h = (subarea->y1 - subarea->y0);
	}
	w = (w + f - 1) >> l2factor;
	h = (h + f - 1) >> l2factor;

	fz_var(tile);
	fz_var(samples);

	fz_try(ctx)
	{
		int alpha = (image->colorspace == NULL);
		if (image->use_colorkey)
			alpha = 1;
		tile = fz_new_pixmap(ctx, image->colorspace, w, h, alpha);
		tile->interpolate = image->interpolate;

		stride = (w * image->n * image->bpc + 7) / 8;

		samples = fz_malloc_array(ctx, h, stride);

		if (subarea)
		{
			int hh;
			unsigned char *s = samples;
			int stream_w = (image->w + f - 1)>>l2factor;
			size_t stream_stride = (stream_w * image->n * image->bpc + 7) / 8;
			int l_margin = subarea->x0 >> l2factor;
			int t_margin = subarea->y0 >> l2factor;
			int r_margin = (image->w + f - 1 - subarea->x1) >> l2factor;
			int b_margin = (image->h + f - 1 - subarea->y1) >> l2factor;
			int l_skip = (l_margin * image->n * image->bpc)/8;
			int r_skip = (r_margin * image->n * image->bpc + 7)/8;
			size_t t_skip = t_margin * stream_stride + l_skip;
			size_t b_skip = b_margin * stream_stride + r_skip;
			size_t l = fz_skip(ctx, stm, t_skip);
			len = 0;
			if (l == t_skip)
			{
				hh = h;
				do
				{
					l = fz_read(ctx, stm, s, stride);
					s += l;
					len += l;
					if (l < stride)
						break;
					if (--hh == 0)
						break;
					l = fz_skip(ctx, stm, r_skip + l_skip);
					if (l < (size_t)(r_skip + l_skip))
						break;
				}
				while (1);
				(void)fz_skip(ctx, stm, r_skip + b_skip);
			}
		}
		else
		{
			len = fz_read(ctx, stm, samples, h * stride);
		}

		/* Pad truncated images */
		if (len < stride * h)
		{
			fz_warn(ctx, "padding truncated image");
			memset(samples + len, 0, stride * h - len);
		}

		/* Invert 1-bit image masks */
		if (image->imagemask)
		{
			/* 0=opaque and 1=transparent so we need to invert */
			unsigned char *p = samples;
			len = h * stride;
			for (i = 0; i < len; i++)
				p[i] = ~p[i];
		}

		fz_unpack_tile(ctx, tile, samples, image->n, image->bpc, stride, indexed);

		fz_free(ctx, samples);
		samples = NULL;

		/* color keyed transparency */
		if (image->use_colorkey && !image->mask)
			fz_mask_color_key(tile, image->n, image->colorkey);

		if (indexed)
		{
			fz_pixmap *conv;
			fz_decode_indexed_tile(ctx, tile, image->decode, (1 << image->bpc) - 1);
			conv = fz_expand_indexed_pixmap(ctx, tile, alpha);
			fz_drop_pixmap(ctx, tile);
			tile = conv;
		}
		else if (image->use_decode)
		{
			fz_decode_tile(ctx, tile, image->decode);
		}

		/* pre-blended matte color */
		if (image->use_colorkey && image->mask)
			fz_unblend_masked_tile(ctx, tile, image);
	}
Example #3
0
fz_pixmap *
fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int in_line, int indexed, int l2factor, int native_l2factor)
{
	fz_pixmap *tile = NULL;
	int stride, len, i;
	unsigned char *samples = NULL;
	int f = 1<<native_l2factor;
	int w = (image->w + f-1) >> native_l2factor;
	int h = (image->h + f-1) >> native_l2factor;

	fz_var(tile);
	fz_var(samples);

	fz_try(ctx)
	{
		tile = fz_new_pixmap(ctx, image->colorspace, w, h);
		tile->interpolate = image->interpolate;

		stride = (w * image->n * image->bpc + 7) / 8;

		samples = fz_malloc_array(ctx, h, stride);

		len = fz_read(stm, samples, h * stride);
		if (len < 0)
		{
			fz_throw(ctx, FZ_ERROR_GENERIC, "cannot read image data");
		}

		/* Make sure we read the EOF marker (for inline images only) */
		if (in_line)
		{
			unsigned char tbuf[512];
			fz_try(ctx)
			{
				int tlen = fz_read(stm, tbuf, sizeof tbuf);
				if (tlen > 0)
					fz_warn(ctx, "ignoring garbage at end of image");
			}
			fz_catch(ctx)
			{
				fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
				fz_warn(ctx, "ignoring error at end of image");
			}
		}

		/* Pad truncated images */
		if (len < stride * h)
		{
			fz_warn(ctx, "padding truncated image");
			memset(samples + len, 0, stride * h - len);
		}

		/* Invert 1-bit image masks */
		if (image->imagemask)
		{
			/* 0=opaque and 1=transparent so we need to invert */
			unsigned char *p = samples;
			len = h * stride;
			for (i = 0; i < len; i++)
				p[i] = ~p[i];
		}

		fz_unpack_tile(tile, samples, image->n, image->bpc, stride, indexed);

		fz_free(ctx, samples);
		samples = NULL;

		if (image->usecolorkey)
			fz_mask_color_key(tile, image->n, image->colorkey);

		if (indexed)
		{
			fz_pixmap *conv;
			fz_decode_indexed_tile(tile, image->decode, (1 << image->bpc) - 1);
			conv = fz_expand_indexed_pixmap(ctx, tile);
			fz_drop_pixmap(ctx, tile);
			tile = conv;
		}
		else
		{
			fz_decode_tile(tile, image->decode);
		}
	}
	fz_always(ctx)
	{
		fz_close(stm);
	}
	fz_catch(ctx)
	{
		if (tile)
			fz_drop_pixmap(ctx, tile);
		fz_free(ctx, samples);

		fz_rethrow(ctx);
	}

	/* Now apply any extra subsampling required */
	if (l2factor - native_l2factor > 0)
	{
		if (l2factor - native_l2factor > 8)
			l2factor = native_l2factor + 8;
		fz_subsample_pixmap(ctx, tile, l2factor - native_l2factor);
	}

	return tile;
}
Example #4
0
fz_pixmap *
fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor, int native_l2factor)
{
	fz_pixmap *tile = NULL;
	int stride, len, i;
	unsigned char *samples = NULL;
	int f = 1<<native_l2factor;
	int w = (image->w + f-1) >> native_l2factor;
	int h = (image->h + f-1) >> native_l2factor;
	/* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1333 */
	int is_banded = indexed < 0;

	fz_var(tile);
	fz_var(samples);

	/* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1333 */
	if (is_banded)
		indexed = -1 - indexed;
	else if (l2factor - native_l2factor > 0 && image->w > (1 << 8))
		return decomp_image_banded(ctx, stm, image, indexed, l2factor, native_l2factor);

	fz_try(ctx)
	{
		tile = fz_new_pixmap(ctx, image->colorspace, w, h);
		tile->interpolate = image->interpolate;

		stride = (w * image->n * image->bpc + 7) / 8;

		samples = fz_malloc_array(ctx, h, stride);

		len = fz_read(stm, samples, h * stride);

		/* Pad truncated images */
		if (len < stride * h)
		{
			fz_warn(ctx, "padding truncated image");
			memset(samples + len, 0, stride * h - len);
		}

		/* Invert 1-bit image masks */
		if (image->imagemask)
		{
			/* 0=opaque and 1=transparent so we need to invert */
			unsigned char *p = samples;
			len = h * stride;
			for (i = 0; i < len; i++)
				p[i] = ~p[i];
		}

		fz_unpack_tile(tile, samples, image->n, image->bpc, stride, indexed);

		fz_free(ctx, samples);
		samples = NULL;

		if (image->usecolorkey && !image->mask)
			fz_mask_color_key(tile, image->n, image->colorkey);

		if (indexed)
		{
			fz_pixmap *conv;
			fz_decode_indexed_tile(tile, image->decode, (1 << image->bpc) - 1);
			conv = fz_expand_indexed_pixmap(ctx, tile);
			fz_drop_pixmap(ctx, tile);
			tile = conv;
		}
		else
		{
			fz_decode_tile(tile, image->decode);
		}

		/* cf. http://bugs.ghostscript.com/show_bug.cgi?id=693517 */
		if (image->usecolorkey && image->mask && !is_banded)
			fz_unblend_masked_tile(ctx, tile, image);
	}
	fz_always(ctx)
	{
		fz_close(stm);
	}
	fz_catch(ctx)
	{
		if (tile)
			fz_drop_pixmap(ctx, tile);
		fz_free(ctx, samples);

		fz_rethrow(ctx);
	}

	/* Now apply any extra subsampling required */
	if (l2factor - native_l2factor > 0)
	{
		if (l2factor - native_l2factor > 8)
			l2factor = native_l2factor + 8;
		fz_subsample_pixmap(ctx, tile, l2factor - native_l2factor);
	}

	return tile;
}