1
0
mirror of synced 2026-04-08 22:31:06 +00:00

*** empty log message ***

This commit is contained in:
Eric Smith
2002-01-22 09:42:42 +00:00
parent e1dbd71ee5
commit 684055a0fc
7 changed files with 294 additions and 104 deletions

View File

@@ -1,6 +1,6 @@
# tiff2pdf: build a PDF file out of one or more TIFF Class F Group 4 files
# Makefile
# $Id: Makefile,v 1.7 2001/12/30 23:24:50 eric Exp $
# $Id: Makefile,v 1.8 2002/01/22 01:41:12 eric Exp $
# Copyright 2001 Eric Smith <eric@brouhaha.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -34,7 +34,7 @@ AUTO_SRCS = scanner.c parser.tab.c
AUTO_HDRS = parser.tab.h
AUTO_MISC = parser.output
tiff2pdf: tiff2pdf.o scanner.o semantics.o parser.tab.o
tiff2pdf: tiff2pdf.o scanner.o semantics.o parser.tab.o bitblt.o
bitblt_test: bitblt_test.o bitblt.o

3
TODO
View File

@@ -1,5 +1,5 @@
tiff2pdf TODO list
$Id: TODO,v 1.4 2002/01/02 05:49:42 eric Exp $
$Id: TODO,v 1.5 2002/01/22 01:40:59 eric Exp $
No particular order. Page numbers refer to _Portable Document Format
Reference Manual_ by Adobe Systems Incorporated, Addison-Wesley, 1993.
@@ -7,6 +7,7 @@ Reference Manual_ by Adobe Systems Incorporated, Addison-Wesley, 1993.
-----------------------------------------------------------------------------
* bitblt library:
* optimize
* replace inner loops in flip_h and flip_v with Duff's Device
* check for endian problems
* crop

299
bitblt.c
View File

@@ -6,7 +6,7 @@
#include "bitblt.h"
#define CALC_ROWBYTES(width) (((width) - 1) / 8 + 1)
#define DIV_ROUND_UP(count,pow2) (((count) - 1) / (pow2) + 1)
static const u8 bit_reverse_byte [0x100] =
@@ -45,8 +45,16 @@ static const u8 bit_reverse_byte [0x100] =
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
static word_type bit_reverse_word (word_type d)
{
return (bit_reverse_byte [d >> 24] |
(bit_reverse_byte [(d >> 16) & 0xff] << 8) |
(bit_reverse_byte [(d >> 8) & 0xff] << 16) |
(bit_reverse_byte [d & 0xff] << 24));
}
static u8 *temp_buffer;
static u32 *temp_buffer;
static u32 temp_buffer_size;
static void realloc_temp_buffer (u32 size)
@@ -63,12 +71,12 @@ static void realloc_temp_buffer (u32 size)
}
static inline u8 pixel_mask (x)
static inline word_type pixel_mask (x)
{
#ifdef LSB_LEFT
return (1 << x);
#else
return (1 << (7 - x));
return (1 << ((BITS_PER_WORD - 1) - x));
#endif
};
@@ -85,8 +93,8 @@ Bitmap *create_bitmap (Rect *rect)
if (! bitmap)
return (NULL);
bitmap->rect = * rect;
bitmap->rowbytes = CALC_ROWBYTES (width);
bitmap->bits = calloc (height * bitmap->rowbytes, 1);
bitmap->row_words = DIV_ROUND_UP (width, BITS_PER_WORD);
bitmap->bits = calloc (1, height * bitmap->row_words * sizeof (word_type));
if (! bitmap->bits)
{
free (bitmap);
@@ -103,33 +111,33 @@ void free_bitmap (Bitmap *bitmap)
boolean get_pixel (Bitmap *bitmap, Point coord)
{
u8 *p;
word_type *p;
if ((coord.x < bitmap->rect.min.x) ||
(coord.x >= bitmap->rect.max.x) ||
(coord.y < bitmap->rect.min.y) ||
(coord.y >= bitmap->rect.max.y))
return (0);
p = bitmap->bits +
(coord.y - bitmap->rect.min.y) * bitmap->rowbytes +
(coord.x - bitmap->rect.min.x) / 8;
return ((*p & pixel_mask (coord.x & 7)) != 0);
(coord.y - bitmap->rect.min.y) * bitmap->row_words +
(coord.x - bitmap->rect.min.x) / BITS_PER_WORD;
return ((*p & pixel_mask (coord.x & (BITS_PER_WORD - 1))) != 0);
}
void set_pixel (Bitmap *bitmap, Point coord, boolean value)
{
u8 *p;
word_type *p;
if ((coord.x < bitmap->rect.min.x) ||
(coord.x >= bitmap->rect.max.x) ||
(coord.y < bitmap->rect.min.y) ||
(coord.y >= bitmap->rect.max.y))
return;
p = bitmap->bits +
(coord.y - bitmap->rect.min.y) * bitmap->rowbytes +
(coord.x - bitmap->rect.min.x) / 8;
(coord.y - bitmap->rect.min.y) * bitmap->row_words +
(coord.x - bitmap->rect.min.x) / BITS_PER_WORD;
if (value)
*p |= pixel_mask (coord.x & 7);
*p |= pixel_mask (coord.x & (BITS_PER_WORD - 1));
else
*p &= (0xff ^ pixel_mask (coord.x & 7));
*p &= ~pixel_mask (coord.x & (BITS_PER_WORD - 1));
}
@@ -166,11 +174,210 @@ static boolean clip_rect (Rect *rect1, Rect *rect2)
}
#if 0
static void blt_background (Bitmap *dest_bitmap,
Rect *dest_rect)
{
s32 y;
word_type *rp;
/* This function requires a non-null dest rect */
assert (dest_rect->min.x < dest_rect->max.x);
assert (dest_rect->min.y < dest_rect->max.y);
/* and that the rows of the dest rect lie entirely within the dest bitmap */
assert (dest_rect->min.y >= dest_bitmap->rect->min.y);
assert (dest_rect->max.y <= dest_bitmap->rect->max.y);
/* clip the x axis of the dest_rect to the bounds of the dest bitmap */
if (dest_rect->min.x < dest_bitmap->rect.min.x)
dest_rect->min.x = dest_bitmap->rect.min.x;
if (dest_rect->max.x > dest_bitmap->rect.max.x)
dest_rect->max.x = dest_bitmap->rect.max.x;
rp = ???;
for (y = 0; y < rect_height (dest_rect); y++)
{
???;
rp += dest_bitmap->row_words;
}
}
static void blt (Bitmap *src_bitmap,
Rect *src_rect,
Bitmap *dest_bitmap,
Rect *dest_rect)
{
s32 y;
word_type *rp;
/* This function requires a non-null src rect */
assert (dest_rect->min.x < dest_rect->max.x);
assert (dest_rect->min.y < dest_rect->max.y);
/* and a non-null dest rect */
assert (dest_rect->min.x < dest_rect->max.x);
assert (dest_rect->min.y < dest_rect->max.y);
/* and that the widths and heights of the rects match */
assert (rect_width (src_rect) == rect_width (dest_rect));
assert (rect_height (src_rect) == rect_height (dest_rect));
/* and that the rows of the src rect lie entirely within the src bitmap */
assert (dest_rect->min.y >= dest_bitmap->rect->min.y);
assert (dest_rect->max.y <= dest_bitmap->rect->max.y);
/* and that the rows of the dest rect lie entirely within the dest bitmap */
assert (dest_rect->min.y >= dest_bitmap->rect->min.y);
assert (dest_rect->max.y <= dest_bitmap->rect->max.y);
/* clip the x axis of the dest_rect to the bounds of the dest bitmap,
and adjust the src_rect to match */
if (dest_rect->min.x < dest_bitmap->rect.min.x)
{
src_rect->min.x += ???;
dest_rect->min.x = dest_bitmap->rect.min.x;
}
if (dest_rect->max.x > dest_bitmap->rect.max.x)
{
dest_rect->max.x = dest_bitmap->rect.max.x;
}
rp = ???;
for (y = 0; y < rect_height (dest_rect); y++)
{
???;
rp += dest_bitmap->row_words;
}
}
Bitmap *bitblt (Bitmap *src_bitmap,
Rect *src_rect,
Bitmap *dest_bitmap,
Point *dest_min,
int tfn)
int tfn,
int background)
{
Rect sr, dr; /* src and dest rects, clipped to visible portion of
dest rect */
u32 drw, drh; /* dest rect width, height - gets adjusted */
Point src_point, dest_point;
{
sr = * src_rect;
u32 srw = rect_width (& sr);
u32 srh = rect_height (& sr);
if ((srw < 0) || (srh < 0))
goto done; /* the source rect is empty! */
dr.min = * dest_min;
dr.max.x = dr.min.x + srw;
dr.max.y = dr.min.y + srh;
}
if (! dest_bitmap)
{
dest_bitmap = create_bitmap (& dr);
if (! dest_bitmap)
return (NULL);
}
if ((dr.min.x >= dest_bitmap->rect.max.x) ||
(dr.min.y >= dest_bitmap->rect.max.y))
goto done; /* the dest rect isn't even in the dest bitmap! */
/* crop dest rect to dest bitmap */
delta = dest_bitmap->rect.min.x - dr.min.x;
if (delta > 0)
{
sr.min.x += delta;
dr.min.x += delta;
}
delta = dest_bitmap->rect.min.y - dr.min.y;
if (delta > 0)
{
sr.min.y += delta;
dr.min.y += delta;
}
delta = dr.max.x - dest_bitmap->rect.max.x;
if (delta > 0)
{
sr.max.x -= delta;
dr.max.x -= delta;
}
delta = dr.max.y - dest_bitmap->rect.max.y;
if (delta > 0)
{
sr.max.x -= delta;
dr.max.x -= delta;
}
drw = rect_width (& dr);
drh = rect_height (& dh);
/* if the source rect min y is >= the source bitmap max y,
we transfer background color to the entire dest rect */
if (sr.min.y >= src->rect.max.y)
{
blt_background (dest_bitmap, & dr);
goto done;
}
/* if the source rect min y is less than the source bitmap min y,
we need to transfer some backgound color to the top part of the dest
rect */
if (sr.min.y < src->rect.min.y)
{
Rect dr2;
uint32 bg_height;
bg_height = src->rect.min.y - sr.min.y;
if (bg_height > sh)
bg_height = sh;
dr2 = dr;
dr2.max.y = dr2.min.y + bg_height;
blt_background (dest_bitmap, & dr2);
/* now reduce the rect height by the number of lines of background
color */
sr.min.y += bg_height;
dr.min.y += bg_height;
sh -= bg_height;
dh -= bg_height;
if (sr.min.y == sr.max.y)
goto done;
}
/* now blt the available rows of the source rect */
/* now transfer the background color to any remaining rows of the
dest rect */
if (??? )
{
blt_background (dest_bitmap, & dr);
}
done:
return (dest_bitmap);
}
#else
Bitmap *bitblt (Bitmap *src_bitmap,
Rect *src_rect,
Bitmap *dest_bitmap,
Point *dest_min,
int tfn,
int background)
{
Point src_point, dest_point;
@@ -206,73 +413,77 @@ Bitmap *bitblt (Bitmap *src_bitmap,
}
return (dest_bitmap);
}
#endif
/* in-place transformations */
void flip_h (Bitmap *src)
{
u8 *rp; /* row pointer */
u8 *p1; /* work src ptr */
u8 *p2; /* work dest ptr */
u16 d;
word_type *rp; /* row pointer */
word_type *p1; /* work src ptr */
word_type *p2; /* work dest ptr */
s32 y;
int shift;
int shift1, shift2;
realloc_temp_buffer (src->rowbytes + 1);
realloc_temp_buffer ((src->row_words + 1) * sizeof (word_type));
rp = src->bits;
if ((rect_width (& src->rect) & 7) == 0)
{
for (y = src->rect.min.y; y < src->rect.max.y; y++)
{
memcpy (temp_buffer, rp, src->rowbytes);
p1 = temp_buffer + src->rowbytes - 1;
memcpy (temp_buffer, rp, src->row_words * sizeof (word_type));
p1 = temp_buffer + src->row_words;
p2 = rp;
while (p1 >= temp_buffer)
*(p2++) = bit_reverse_byte [*(p1--)];
*(p2++) = bit_reverse_word (*(p1--));
rp += src->rowbytes;
rp += src->row_words;
}
return;
}
temp_buffer [0] = 0;
shift = 8 - (rect_width (& src->rect) & 7);
shift1 = rect_width (& src->rect) & (BITS_PER_WORD - 1);
shift2 = BITS_PER_WORD - shift1;
for (y = src->rect.min.y; y < src->rect.max.y; y++)
{
memcpy (temp_buffer + 1, rp, src->rowbytes);
p1 = temp_buffer + src->rowbytes;
word_type d1, d2;
memcpy (temp_buffer + 1, rp, src->row_words * sizeof (word_type));
p1 = temp_buffer + src->row_words;
p2 = rp;
d = *(p1--);
d2 = *(p1--);
while (p1 >= temp_buffer)
{
d = (d >> 8) | ((*(p1--)) << 8);
*(p2++) = bit_reverse_byte [(d >> shift) & 0xff];
d1 = *(p1--);
*(p2++) = bit_reverse_word ((d1 << shift1) | (d2 >> shift2));
d2 = d1;
}
rp += src->rowbytes;
rp += src->row_words;
}
}
void flip_v (Bitmap *src)
{
u8 *p1, *p2;
word_type *p1, *p2;
realloc_temp_buffer (src->rowbytes);
realloc_temp_buffer (src->row_words * sizeof (word_type));
p1 = src->bits;
p2 = src->bits + src->rowbytes * (rect_height (& src->rect) - 1);
p2 = src->bits + src->row_words * (rect_height (& src->rect) - 1);
while (p1 < p2)
{
memcpy (temp_buffer, p1, src->rowbytes);
memcpy (p1, p2, src->rowbytes);
memcpy (p2, temp_buffer, src->rowbytes);
p1 += src->rowbytes;
p2 -= src->rowbytes;
memcpy (temp_buffer, p1, src->row_words * sizeof (word_type));
memcpy (p1, p2, src->row_words * sizeof (word_type));
memcpy (p2, temp_buffer, src->row_words * sizeof (word_type));
p1 += src->row_words;
p2 -= src->row_words;
}
}
@@ -285,10 +496,10 @@ void rot_180 (Bitmap *src) /* combination of flip_h and flip_v */
/* "in-place" transformations - will allocate new memory and free old */
void transpose (Bitmap *src)
{
u32 new_rowbytes = CALC_ROWBYTES (rect_height (& src->rect));
u8 *new_bits;
u32 new_row_words = DIV_ROUND_UP (rect_height (& src->rect), 32);
word_type *new_bits;
new_bits = calloc (1, new_rowbytes * rect_width (& src->rect));
new_bits = calloc (1, new_row_words * rect_width (& src->rect) * sizeof (word_type));
/* $$$ more code needed here */
}

View File

@@ -20,11 +20,18 @@ static inline s32 rect_height (Rect *r)
return (r->max.y - r->min.y);
}
/*
* Despite the following two definitions, there are still some places
* in the code that depend on words having 32 bits.
*/
#define BITS_PER_WORD 32
typedef u32 word_type;
typedef struct Bitmap
{
u8 *bits;
word_type *bits;
Rect rect;
u32 rowbytes;
u32 row_words;
} Bitmap;
@@ -45,7 +52,8 @@ Bitmap *bitblt (Bitmap *src_bitmap,
Rect *src_rect,
Bitmap *dest_bitmap,
Point *dest_min,
int tfn);
int tfn,
int background);
/* in-place transformations */

View File

@@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include "type.h"
#include "bitblt.h"
@@ -24,8 +25,9 @@ Bitmap *setup (void)
{
Bitmap *b;
Point p;
Rect r = {{ 0, 0 }, { WIDTH, HEIGHT }};
b = create_bitmap (WIDTH, HEIGHT);
b = create_bitmap (& r);
if (! b)
return (NULL);
@@ -39,10 +41,10 @@ Bitmap *setup (void)
void print_bitmap (FILE *o, Bitmap *b)
{
Point p;
printf ("rowbytes: %d\n", b->rowbytes);
for (p.y = 0; p.y < b->height; p.y++)
printf ("row_words: %d\n", b->row_words);
for (p.y = b->rect.min.y; p.y < b->rect.max.y; p.y++)
{
for (p.x = 0; p.x < b->width; p.x++)
for (p.x = b->rect.min.x; p.x < b->rect.max.x; p.x++)
fputc (".X" [get_pixel (b, p)], o);
fprintf (o, "\n");
}
@@ -64,18 +66,19 @@ int main (int argc, char *argv[])
}
print_bitmap (stdout, b);
printf ("\n");
flip_v (b);
print_bitmap (stdout, b);
printf ("\n");
flip_h (b);
print_bitmap (stdout, b);
printf ("\n");
#if 0
b2 = create_bitmap (b->height, b->width);
if (! b2)
{
fprintf (stderr, "create_bitmap failed\n");
exit (2);
}
#endif
r.upper_left.x = r.upper_left.y = 0;
r.lower_right.x = b->width;
r.lower_right.y = b->height;
@@ -92,6 +95,7 @@ int main (int argc, char *argv[])
}
print_bitmap (stdout, b2);
#endif
exit (0);
}

25
t2p.c
View File

@@ -5,7 +5,7 @@
* encoding.
*
* Main program
* $Id: t2p.c,v 1.14 2002/01/02 08:39:39 eric Exp $
* $Id: t2p.c,v 1.15 2002/01/22 01:42:42 eric Exp $
* Copyright 2001 Eric Smith <eric@brouhaha.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -200,7 +200,7 @@ static Bitmap *resize_bitmap (Bitmap *src,
dest_min.x = 0;
dest_min.y = 0;
dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC);
dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC, 0);
free_bitmap (src);
return (dest);
}
@@ -244,8 +244,6 @@ boolean process_page (int image, /* range 1 .. n */
float x_resolution, y_resolution;
float dest_x_resolution, dest_y_resolution;
int scanline_size;
int width_points, height_points; /* really 1/72 inch units rather than
points */
@@ -358,8 +356,6 @@ boolean process_page (int image, /* range 1 .. n */
dest_y_resolution = y_resolution;
}
scanline_size = TIFFScanlineSize (in);
rect.min.x = 0;
rect.min.y = 0;
rect.max.x = image_width;
@@ -373,22 +369,9 @@ boolean process_page (int image, /* range 1 .. n */
goto fail;
}
if (bitmap->rowbytes != scanline_size)
{
printf ("image_width %d\n", image_width);
printf ("rowbytes %d\n", bitmap->rowbytes);
printf ("TIFFScanlineSize %d\n", scanline_size);
}
for (row = 0; row < image_length; row++)
TIFFReadScanline (in,
bitmap->bits + row * bitmap->rowbytes,
row,
0);
for (row = 0; row < dest_image_length; row++)
if (1 != TIFFReadScanline (in,
bitmap->bits + row * bitmap->rowbytes,
bitmap->bits + row * bitmap->row_words,
row,
0))
{
@@ -435,7 +418,7 @@ boolean process_page (int image, /* range 1 .. n */
for (row = 0; row < rect_height (& bitmap->rect); row++)
if (1 != TIFFWriteScanline (tiff_temp,
bitmap->bits + row * bitmap->rowbytes,
bitmap->bits + row * bitmap->row_words,
row,
0))
{

View File

@@ -5,7 +5,7 @@
* encoding.
*
* Main program
* $Id: tumble.c,v 1.14 2002/01/02 08:39:39 eric Exp $
* $Id: tumble.c,v 1.15 2002/01/22 01:42:42 eric Exp $
* Copyright 2001 Eric Smith <eric@brouhaha.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -200,7 +200,7 @@ static Bitmap *resize_bitmap (Bitmap *src,
dest_min.x = 0;
dest_min.y = 0;
dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC);
dest = bitblt (src, & src_rect, NULL, & dest_min, TF_SRC, 0);
free_bitmap (src);
return (dest);
}
@@ -244,8 +244,6 @@ boolean process_page (int image, /* range 1 .. n */
float x_resolution, y_resolution;
float dest_x_resolution, dest_y_resolution;
int scanline_size;
int width_points, height_points; /* really 1/72 inch units rather than
points */
@@ -358,8 +356,6 @@ boolean process_page (int image, /* range 1 .. n */
dest_y_resolution = y_resolution;
}
scanline_size = TIFFScanlineSize (in);
rect.min.x = 0;
rect.min.y = 0;
rect.max.x = image_width;
@@ -373,22 +369,9 @@ boolean process_page (int image, /* range 1 .. n */
goto fail;
}
if (bitmap->rowbytes != scanline_size)
{
printf ("image_width %d\n", image_width);
printf ("rowbytes %d\n", bitmap->rowbytes);
printf ("TIFFScanlineSize %d\n", scanline_size);
}
for (row = 0; row < image_length; row++)
TIFFReadScanline (in,
bitmap->bits + row * bitmap->rowbytes,
row,
0);
for (row = 0; row < dest_image_length; row++)
if (1 != TIFFReadScanline (in,
bitmap->bits + row * bitmap->rowbytes,
bitmap->bits + row * bitmap->row_words,
row,
0))
{
@@ -435,7 +418,7 @@ boolean process_page (int image, /* range 1 .. n */
for (row = 0; row < rect_height (& bitmap->rect); row++)
if (1 != TIFFWriteScanline (tiff_temp,
bitmap->bits + row * bitmap->rowbytes,
bitmap->bits + row * bitmap->row_words,
row,
0))
{