Add very many enhancements by J. David Bryan.
This commit is contained in:
29
Makefile
29
Makefile
@@ -17,6 +17,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
#
|
||||
# 2010-09-02 [JDB] Allow building in a directory separate from the source and
|
||||
# add PNG and blank-page support files. Also change the
|
||||
# "include" of dependencies to suppress an error if the
|
||||
# dependency files are not present.
|
||||
|
||||
|
||||
# Conditionals: uncomment the following defines as nessary. Note that a
|
||||
@@ -29,7 +34,7 @@
|
||||
CTL_LANG=1
|
||||
|
||||
|
||||
CFLAGS = -Wall
|
||||
CFLAGS = -Wall -Wno-unused-function -Wno-unused-but-set-variable
|
||||
LDFLAGS =
|
||||
LDLIBS = -ltiff -ljpeg -lnetpbm -lz -lm
|
||||
|
||||
@@ -49,6 +54,7 @@ LDLIBS := -Wl,-static $(LDLIBS)
|
||||
endif
|
||||
|
||||
|
||||
LEX = flex
|
||||
YACC = bison
|
||||
YFLAGS = -d -v
|
||||
|
||||
@@ -58,18 +64,18 @@ YFLAGS = -d -v
|
||||
# let me know why so I can improve this Makefile.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
VERSION = 0.33
|
||||
VERSION = 0.34
|
||||
|
||||
PACKAGE = tumble
|
||||
|
||||
TARGETS = tumble
|
||||
|
||||
CSRCS = tumble.c semantics.c \
|
||||
tumble_input.c tumble_tiff.c tumble_jpeg.c tumble_pbm.c \
|
||||
CSRCS = tumble.c semantics.c tumble_input.c \
|
||||
tumble_tiff.c tumble_jpeg.c tumble_pbm.c tumble_png.c tumble_blank.c \
|
||||
bitblt.c bitblt_table_gen.c bitblt_g4.c g4_table_gen.c \
|
||||
pdf.c pdf_util.c pdf_prim.c pdf_name_tree.c \
|
||||
pdf_bookmark.c pdf_page_label.c \
|
||||
pdf_text.c pdf_g4.c pdf_jpeg.c
|
||||
pdf_text.c pdf_g4.c pdf_jpeg.c pdf_png.c
|
||||
OSRCS = scanner.l parser.y
|
||||
HDRS = tumble.h tumble_input.h semantics.h bitblt.h bitblt_tables.h \
|
||||
pdf.h pdf_private.h pdf_util.h pdf_prim.h pdf_name_tree.h
|
||||
@@ -106,12 +112,12 @@ CFLAGS := $(CFLAGS) $(CDEFINES)
|
||||
all: $(TARGETS) $(TEST_TARGETS)
|
||||
|
||||
|
||||
TUMBLE_OBJS = tumble.o semantics.o \
|
||||
tumble_input.o tumble_tiff.o tumble_jpeg.o tumble_pbm.o \
|
||||
TUMBLE_OBJS = tumble.o semantics.o tumble_input.o \
|
||||
tumble_tiff.o tumble_jpeg.o tumble_pbm.o tumble_png.o tumble_blank.o \
|
||||
bitblt.o bitblt_g4.o bitblt_tables.o g4_tables.o \
|
||||
pdf.o pdf_util.o pdf_prim.o pdf_name_tree.o \
|
||||
pdf_bookmark.o pdf_page_label.o \
|
||||
pdf_text.o pdf_g4.o pdf_jpeg.o
|
||||
pdf_text.o pdf_g4.o pdf_jpeg.o pdf_png.o
|
||||
|
||||
ifdef CTL_LANG
|
||||
TUMBLE_OBJS += scanner.o parser.tab.o
|
||||
@@ -119,9 +125,6 @@ endif
|
||||
|
||||
tumble: $(TUMBLE_OBJS)
|
||||
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
ifndef DEBUG
|
||||
strip $@
|
||||
endif
|
||||
|
||||
|
||||
bitblt_tables.h: bitblt_table_gen
|
||||
@@ -178,6 +181,6 @@ ALL_CSRCS = $(CSRCS) $(AUTO_CSRCS) $(TEST_CSRCS)
|
||||
DEPENDS = $(ALL_CSRCS:.c=.d)
|
||||
|
||||
%.d: %.c
|
||||
$(CC) -M -MG $(CFLAGS) $< | sed -e 's@ /[^ ]*@@g' -e 's@^\(.*\)\.o:@\1.d \1.o:@' > $@
|
||||
$(CC) -M -MG $(CFLAGS) $< | sed -e 's@ \([A-Za-z]\):/@ /\1/@g' -e 's@^\(.*\)\.o:@\1.d \1.o:@' > $@
|
||||
|
||||
include $(DEPENDS)
|
||||
-include $(DEPENDS)
|
||||
|
||||
7
bitblt.h
7
bitblt.h
@@ -19,8 +19,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-13 [JDB] pm_config.h (part of NETPBM) defines BITS_PER_WORD but
|
||||
* apparently doesn't use it externally. We undefine it here
|
||||
* so that our version takes precedence and warnings are not
|
||||
* generated.
|
||||
*/
|
||||
|
||||
#undef BITS_PER_WORD
|
||||
|
||||
|
||||
typedef struct Point
|
||||
{
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2007-06-20 [JDB] Fixed a bug wherein "g4_get_pixel" is called with pixel
|
||||
* index == width, causing an index off the end of the array
|
||||
* if width % BITS_PER_WORD == 0.
|
||||
*/
|
||||
|
||||
|
||||
@@ -303,7 +307,7 @@ void bitblt_write_g4 (Bitmap *bitmap, FILE *f)
|
||||
word_t *cur_line;
|
||||
word_t *ref_line; /* reference (previous) row */
|
||||
|
||||
temp_buffer = pdf_calloc ((width + BITS_PER_WORD - 1) / BITS_PER_WORD,
|
||||
temp_buffer = pdf_calloc (width / BITS_PER_WORD + 1,
|
||||
sizeof (word_t));
|
||||
|
||||
cur_line = bitmap->bits;
|
||||
|
||||
65
parser.y
65
parser.y
@@ -19,15 +19,23 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*/
|
||||
*
|
||||
* 2009-03-13 [JDB] Add support for blank pages, overlay images, color
|
||||
* mapping, color-key masking, and push/pop of input
|
||||
* contexts.
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "semantics.h"
|
||||
|
||||
extern int yylex (void);
|
||||
%}
|
||||
|
||||
%error-verbose
|
||||
|
||||
%union {
|
||||
int integer;
|
||||
char character;
|
||||
@@ -36,6 +44,9 @@
|
||||
page_size_t size;
|
||||
range_t range;
|
||||
page_label_t page_label;
|
||||
overlay_t overlay;
|
||||
rgb_t rgb;
|
||||
rgb_range_t rgb_range;
|
||||
}
|
||||
|
||||
%token <integer> INTEGER
|
||||
@@ -63,9 +74,13 @@
|
||||
%token CROP
|
||||
%token SIZE
|
||||
%token RESOLUTION
|
||||
%token BLANK
|
||||
%token INPUT
|
||||
|
||||
%token TRANSPARENT
|
||||
%token COLORMAP
|
||||
%token LABEL
|
||||
%token OVERLAY
|
||||
%token PAGE
|
||||
%token PAGES
|
||||
%token BOOKMARK
|
||||
@@ -89,6 +104,12 @@
|
||||
|
||||
%type <size> page_size
|
||||
|
||||
%type <rgb> rgb
|
||||
|
||||
%type <rgb_range> rgb_range
|
||||
%type <rgb_range> gray_range
|
||||
%type <rgb_range> color_range
|
||||
|
||||
%%
|
||||
|
||||
statements:
|
||||
@@ -157,8 +178,21 @@ size_clause:
|
||||
resolution_clause:
|
||||
RESOLUTION FLOAT unit ;
|
||||
|
||||
rgb_range:
|
||||
'(' range range range ')' { $$.red = $2; $$.green = $3; $$.blue = $4; }
|
||||
|
||||
gray_range:
|
||||
'(' range ')' { $$.red = $2; $$.green = $2; $$.blue = $2; } ;
|
||||
|
||||
color_range:
|
||||
rgb_range
|
||||
| gray_range;
|
||||
|
||||
transparency_clause:
|
||||
TRANSPARENT color_range ';' { input_set_transparency ($2); } ;
|
||||
|
||||
modifier_clause:
|
||||
rotate_clause | crop_clause | size_clause | resolution_clause;
|
||||
rotate_clause | crop_clause | size_clause | resolution_clause | transparency_clause;
|
||||
|
||||
modifier_clauses:
|
||||
modifier_clause
|
||||
@@ -175,12 +209,16 @@ part_clause:
|
||||
modifier_clause_list ';'
|
||||
{ input_set_modifier_context (INPUT_MODIFIER_ALL); } ;
|
||||
|
||||
blank_page_clause:
|
||||
BLANK { input_set_file (NULL); } size_clause ;
|
||||
|
||||
input_clause:
|
||||
input_file_clause
|
||||
| image_clause
|
||||
| images_clause
|
||||
| part_clause
|
||||
| modifier_clause
|
||||
| blank_page_clause
|
||||
| input_clause_list ;
|
||||
|
||||
input_clauses:
|
||||
@@ -188,7 +226,8 @@ input_clauses:
|
||||
| input_clauses input_clause ;
|
||||
|
||||
input_clause_list:
|
||||
'{' input_clauses '}' ;
|
||||
'{' { input_push_context (); }
|
||||
input_clauses '}' { input_pop_context (); } ;
|
||||
|
||||
input_statement:
|
||||
INPUT input_clauses ;
|
||||
@@ -218,12 +257,23 @@ label_clause:
|
||||
| LABEL CHARACTER ';' { page_label_t label = { NULL, $2 }; output_set_page_label (label); }
|
||||
| LABEL STRING ',' CHARACTER ';' { page_label_t label = { $2, $4 }; output_set_page_label (label); } ;
|
||||
|
||||
overlay_clause_list:
|
||||
/* empty */
|
||||
| '{' overlay_clauses '}' ;
|
||||
|
||||
overlay_clauses:
|
||||
overlay_clause
|
||||
| overlay_clauses overlay_clause ;
|
||||
|
||||
overlay_clause:
|
||||
OVERLAY length ',' length ';' { overlay_t overlay = { $2, $4 }; output_overlay (overlay); } ;
|
||||
|
||||
page_ranges:
|
||||
range { output_pages ($1); }
|
||||
| page_ranges ',' range { output_pages ($3); } ;
|
||||
|
||||
page_clause:
|
||||
PAGE INTEGER ';' { range_t range = { $2, $2 }; output_pages (range); } ;
|
||||
PAGE INTEGER { range_t range = { $2, $2 }; output_pages (range); } overlay_clause_list ';' ;
|
||||
|
||||
pages_clause:
|
||||
PAGES page_ranges ';' ;
|
||||
@@ -240,8 +290,15 @@ bookmark_clause:
|
||||
bookmark_name_list
|
||||
output_clause_list ';' { bookmark_level--; output_pop_context (); } ;
|
||||
|
||||
rgb:
|
||||
'(' INTEGER INTEGER INTEGER ')' { $$.red = $2; $$.green = $3; $$.blue = $4; } ;
|
||||
|
||||
colormap_clause:
|
||||
COLORMAP rgb ',' rgb ';' { output_set_colormap ($2, $4); } ;
|
||||
|
||||
output_clause:
|
||||
output_file_clause
|
||||
| colormap_clause
|
||||
| label_clause
|
||||
| page_clause | pages_clause
|
||||
| bookmark_clause
|
||||
|
||||
27
pdf.c
27
pdf.c
@@ -19,6 +19,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2005-05-03 [JDB] Add CreationDate and ModDate PDF headers.
|
||||
* 2014-02-18 [JDB] Use PDF_PRODUCER definition.
|
||||
*/
|
||||
|
||||
|
||||
@@ -26,6 +29,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "bitblt.h"
|
||||
@@ -70,6 +74,11 @@ struct pdf_pages *pdf_new_pages (pdf_file_handle pdf_file)
|
||||
pdf_file_handle pdf_create (char *filename)
|
||||
{
|
||||
pdf_file_handle pdf_file;
|
||||
time_t current_time, adjusted_time;
|
||||
struct tm *time_and_date;
|
||||
int gmt_diff;
|
||||
char tm_string[18], gmt_string[24];
|
||||
const char tm_format[] = "D:%Y%m%d%H%M%S";
|
||||
|
||||
pdf_file = pdf_calloc (1, sizeof (struct pdf_file));
|
||||
|
||||
@@ -88,7 +97,23 @@ pdf_file_handle pdf_create (char *filename)
|
||||
pdf_set_dict_entry (pdf_file->catalog, "PageLayout", pdf_new_name ("SinglePage"));
|
||||
|
||||
pdf_file->info = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY));
|
||||
pdf_set_info (pdf_file, "Producer", "tumble by Eric Smith -- http://tumble.brouhaha.com/");
|
||||
pdf_set_info (pdf_file, "Producer", PDF_PRODUCER);
|
||||
|
||||
/* Generate CreationDate and ModDate */
|
||||
|
||||
current_time = time (NULL);
|
||||
time_and_date = gmtime (¤t_time);
|
||||
adjusted_time = mktime (time_and_date);
|
||||
gmt_diff = (int) difftime (current_time, adjusted_time);
|
||||
|
||||
time_and_date = localtime (¤t_time);
|
||||
|
||||
if (strftime (tm_string, sizeof (tm_string), tm_format, time_and_date))
|
||||
{
|
||||
sprintf (gmt_string, "%s%+03d'%02d'", tm_string, gmt_diff / 3600, gmt_diff % 60);
|
||||
pdf_set_info (pdf_file, "CreationDate", gmt_string);
|
||||
pdf_set_info (pdf_file, "ModDate", gmt_string);
|
||||
}
|
||||
|
||||
pdf_file->trailer_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
/* Size key will be added later */
|
||||
|
||||
75
pdf.h
75
pdf.h
@@ -19,14 +19,46 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2007-06-28 [JDB] Increase page limits from 45" to 200" square.
|
||||
* 2010-09-02 [JDB] Added support for min-is-black TIFF images.
|
||||
* 2014-02-18 [JDB] Added PDF_PRODUCER definition.
|
||||
*/
|
||||
|
||||
#if !defined(SEMANTICS)
|
||||
typedef struct
|
||||
{
|
||||
int first;
|
||||
int last;
|
||||
} range_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int red;
|
||||
int green;
|
||||
int blue;
|
||||
} rgb_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
range_t red;
|
||||
range_t green;
|
||||
range_t blue;
|
||||
} rgb_range_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rgb_t black_map;
|
||||
rgb_t white_map;
|
||||
} colormap_t;
|
||||
#endif
|
||||
|
||||
/* Acrobat default units aren't really points, but they're close. */
|
||||
#define POINTS_PER_INCH 72.0
|
||||
|
||||
/* page size limited by Acrobat Reader to 45 inches on a side */
|
||||
#define PAGE_MAX_INCHES 45
|
||||
/* Page size for Acrobat Reader 4.0 and later is 200 x 200 inches.
|
||||
Old limit of 45 inches applied to Acrobat Reader 3.x only. */
|
||||
#define PAGE_MAX_INCHES 200
|
||||
#define PAGE_MAX_POINTS (PAGE_MAX_INCHES * POINTS_PER_INCH)
|
||||
|
||||
|
||||
@@ -48,11 +80,18 @@ pdf_file_handle pdf_create (char *filename);
|
||||
|
||||
void pdf_close (pdf_file_handle pdf_file, int page_mode);
|
||||
|
||||
#define AS_STR(S) #S
|
||||
#define TO_STR(S) AS_STR(S)
|
||||
|
||||
#define PDF_PRODUCER "tumble " TO_STR(TUMBLE_VERSION) \
|
||||
" by Eric Smith (modified by J. David Bryan)"
|
||||
|
||||
void pdf_set_author (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_creator (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_title (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_subject (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_keywords (pdf_file_handle pdf_file, char *author);
|
||||
void pdf_set_creator (pdf_file_handle pdf_file, char *creator);
|
||||
void pdf_set_producer (pdf_file_handle pdf_file, char *producer);
|
||||
void pdf_set_title (pdf_file_handle pdf_file, char *title);
|
||||
void pdf_set_subject (pdf_file_handle pdf_file, char *subject);
|
||||
void pdf_set_keywords (pdf_file_handle pdf_file, char *keywords);
|
||||
|
||||
|
||||
/* width and height in units of 1/72 inch */
|
||||
@@ -74,12 +113,10 @@ void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
double y,
|
||||
double width,
|
||||
double height,
|
||||
bool negative,
|
||||
Bitmap *bitmap,
|
||||
bool ImageMask,
|
||||
double r, /* RGB fill color, only for ImageMask */
|
||||
double g,
|
||||
double b,
|
||||
bool BlackIs1); /* boolean, typ. false */
|
||||
colormap_t *colormap,
|
||||
rgb_range_t *transparency);
|
||||
|
||||
|
||||
void pdf_write_jpeg_image (pdf_page_handle pdf_page,
|
||||
@@ -90,9 +127,25 @@ void pdf_write_jpeg_image (pdf_page_handle pdf_page,
|
||||
bool color,
|
||||
uint32_t width_samples,
|
||||
uint32_t height_samples,
|
||||
rgb_range_t *transparency,
|
||||
FILE *f);
|
||||
|
||||
|
||||
void pdf_write_png_image (pdf_page_handle pdf_page,
|
||||
double x,
|
||||
double y,
|
||||
double width,
|
||||
double height,
|
||||
int color,
|
||||
char *pal,
|
||||
int palent,
|
||||
int bpp,
|
||||
uint32_t width_samples,
|
||||
uint32_t height_samples,
|
||||
rgb_range_t *transparency,
|
||||
FILE *f);
|
||||
|
||||
|
||||
void pdf_set_page_number (pdf_page_handle pdf_page, char *page_number);
|
||||
|
||||
/* Create a new bookmark, under the specified parent, or at the top
|
||||
|
||||
89
pdf_g4.c
89
pdf_g4.c
@@ -19,6 +19,12 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2008-12-30 [JDB] Fixed bug wherein "pdf_write_g4_content_callback" called
|
||||
* "pdf_stream_printf" to write XObject name without escaping
|
||||
* restricted characters. Now calls "pdf_write_name".
|
||||
*
|
||||
* 2010-09-02 [JDB] Added support for min-is-black TIFF images.
|
||||
*/
|
||||
|
||||
|
||||
@@ -40,11 +46,8 @@ struct pdf_g4_image
|
||||
{
|
||||
double width, height;
|
||||
double x, y;
|
||||
double r, g, b; /* fill color, only for ImageMask */
|
||||
unsigned long Columns;
|
||||
unsigned long Rows;
|
||||
bool ImageMask;
|
||||
bool BlackIs1;
|
||||
Bitmap *bitmap;
|
||||
char XObject_name [4];
|
||||
};
|
||||
@@ -60,12 +63,9 @@ static void pdf_write_g4_content_callback (pdf_file_handle pdf_file,
|
||||
pdf_stream_printf (pdf_file, stream, "q %g 0 0 %g %g %g cm ",
|
||||
image->width, image->height,
|
||||
image->x, image->y);
|
||||
if (image->ImageMask)
|
||||
pdf_stream_printf (pdf_file, stream, "%g %g %g rg ",
|
||||
image->r, image->g, image->b);
|
||||
|
||||
pdf_stream_printf (pdf_file, stream, "/%s Do Q\r\n",
|
||||
image->XObject_name);
|
||||
pdf_write_name (pdf_file, image->XObject_name);
|
||||
pdf_stream_printf (pdf_file, stream, "Do Q\r\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -84,12 +84,10 @@ void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
double y,
|
||||
double width,
|
||||
double height,
|
||||
bool negative,
|
||||
Bitmap *bitmap,
|
||||
bool ImageMask,
|
||||
double r, /* RGB fill color, only for ImageMask */
|
||||
double g,
|
||||
double b,
|
||||
bool BlackIs1) /* boolean, typ. false */
|
||||
colormap_t *colormap,
|
||||
rgb_range_t *transparency)
|
||||
{
|
||||
struct pdf_g4_image *image;
|
||||
|
||||
@@ -99,6 +97,16 @@ void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
|
||||
struct pdf_obj *content_stream;
|
||||
|
||||
struct pdf_obj *contents;
|
||||
struct pdf_obj *mask;
|
||||
|
||||
typedef char MAP_STRING[6];
|
||||
|
||||
MAP_STRING color_index;
|
||||
static MAP_STRING last_color_index;
|
||||
static struct pdf_obj *color_space;
|
||||
|
||||
|
||||
pdf_add_array_elem_unique (pdf_page->procset, pdf_new_name ("ImageB"));
|
||||
|
||||
image = pdf_calloc (1, sizeof (struct pdf_g4_image));
|
||||
@@ -107,15 +115,10 @@ void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
image->height = height;
|
||||
image->x = x;
|
||||
image->y = y;
|
||||
image->r = r;
|
||||
image->g = g;
|
||||
image->b = b;
|
||||
|
||||
image->bitmap = bitmap;
|
||||
image->Columns = bitmap->rect.max.x - bitmap->rect.min.x;
|
||||
image->Rows = bitmap->rect.max.y - bitmap->rect.min.y;
|
||||
image->ImageMask = ImageMask;
|
||||
image->BlackIs1 = BlackIs1;
|
||||
|
||||
stream_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
|
||||
@@ -134,8 +137,42 @@ void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (image->Columns));
|
||||
pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (image->Rows));
|
||||
pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (1));
|
||||
if (ImageMask)
|
||||
pdf_set_dict_entry (stream_dict, "ImageMask", pdf_new_bool (ImageMask));
|
||||
|
||||
if (transparency)
|
||||
{
|
||||
mask = pdf_new_obj (PT_ARRAY);
|
||||
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->red.first));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->red.last));
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "Mask", mask);
|
||||
}
|
||||
|
||||
if (colormap)
|
||||
{
|
||||
color_index [0] = (char) colormap->black_map.red;
|
||||
color_index [1] = (char) colormap->black_map.green;
|
||||
color_index [2] = (char) colormap->black_map.blue;
|
||||
color_index [3] = (char) colormap->white_map.red;
|
||||
color_index [4] = (char) colormap->white_map.green;
|
||||
color_index [5] = (char) colormap->white_map.blue;
|
||||
|
||||
if ((color_space == NULL) ||
|
||||
(memcmp (color_index, last_color_index, sizeof (MAP_STRING)) != 0))
|
||||
{
|
||||
memcpy (last_color_index, color_index, sizeof (MAP_STRING));
|
||||
|
||||
color_space = pdf_new_obj (PT_ARRAY);
|
||||
pdf_add_array_elem (color_space, pdf_new_name ("Indexed"));
|
||||
pdf_add_array_elem (color_space, pdf_new_name ("DeviceRGB"));
|
||||
pdf_add_array_elem (color_space, pdf_new_integer (1));
|
||||
pdf_add_array_elem (color_space, pdf_new_string_n (color_index, 6));
|
||||
|
||||
color_space = pdf_new_ind_ref (pdf_page->pdf_file, color_space);
|
||||
}
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "ColorSpace", color_space);
|
||||
}
|
||||
else
|
||||
pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name ("DeviceGray"));
|
||||
|
||||
@@ -153,10 +190,10 @@ void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
"Rows",
|
||||
pdf_new_integer (image->Rows));
|
||||
|
||||
if (BlackIs1)
|
||||
if (negative)
|
||||
pdf_set_dict_entry (decode_parms,
|
||||
"BlackIs1",
|
||||
pdf_new_bool (BlackIs1));
|
||||
pdf_new_bool (true));
|
||||
|
||||
pdf_stream_add_filter (stream, "CCITTFaxDecode", decode_parms);
|
||||
|
||||
@@ -170,7 +207,13 @@ void pdf_write_g4_fax_image (pdf_page_handle pdf_page,
|
||||
& pdf_write_g4_content_callback,
|
||||
image));
|
||||
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
|
||||
contents = pdf_get_dict_entry (pdf_page->page_dict, "Contents");
|
||||
|
||||
if (! contents)
|
||||
contents = pdf_new_obj (PT_ARRAY);
|
||||
|
||||
pdf_add_array_elem (contents, content_stream);
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", contents);
|
||||
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
|
||||
}
|
||||
|
||||
39
pdf_jpeg.c
39
pdf_jpeg.c
@@ -19,6 +19,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2008-12-30 [JDB] Fixed bug wherein "pdf_write_jpeg_content_callback" called
|
||||
* "pdf_stream_printf" to write XObject name without escaping
|
||||
* restricted characters. Now calls "pdf_write_name".
|
||||
*/
|
||||
|
||||
|
||||
@@ -57,8 +61,8 @@ static void pdf_write_jpeg_content_callback (pdf_file_handle pdf_file,
|
||||
pdf_stream_printf (pdf_file, stream, "q %g 0 0 %g %g %g cm ",
|
||||
image->width, image->height,
|
||||
image->x, image->y);
|
||||
pdf_stream_printf (pdf_file, stream, "/%s Do Q\r\n",
|
||||
image->XObject_name);
|
||||
pdf_write_name (pdf_file, image->XObject_name);
|
||||
pdf_stream_printf (pdf_file, stream, "Do Q\r\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +105,7 @@ void pdf_write_jpeg_image (pdf_page_handle pdf_page,
|
||||
bool color,
|
||||
uint32_t width_samples,
|
||||
uint32_t height_samples,
|
||||
rgb_range_t *transparency,
|
||||
FILE *f)
|
||||
{
|
||||
struct pdf_jpeg_image *image;
|
||||
@@ -110,6 +115,9 @@ void pdf_write_jpeg_image (pdf_page_handle pdf_page,
|
||||
|
||||
struct pdf_obj *content_stream;
|
||||
|
||||
struct pdf_obj *contents;
|
||||
struct pdf_obj *mask;
|
||||
|
||||
image = pdf_calloc (1, sizeof (struct pdf_jpeg_image));
|
||||
|
||||
image->width = width;
|
||||
@@ -139,13 +147,28 @@ void pdf_write_jpeg_image (pdf_page_handle pdf_page,
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "Type", pdf_new_name ("XObject"));
|
||||
pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
|
||||
// Name is required in PDF 1.0 but obsoleted in later PDF versions
|
||||
// pdf_set_dict_entry (stream_dict, "Name", pdf_new_name (& image->XObject_name [0]));
|
||||
pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (image->width_samples));
|
||||
pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (image->height_samples));
|
||||
pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name (image->color ? "DeviceRGB" : "DeviceGray"));
|
||||
pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (8));
|
||||
|
||||
if (transparency)
|
||||
{
|
||||
mask = pdf_new_obj (PT_ARRAY);
|
||||
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->red.first));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->red.last));
|
||||
|
||||
if (image->color) {
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->green.first));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->green.last));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->blue.first));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->blue.last));
|
||||
}
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "Mask", mask);
|
||||
}
|
||||
|
||||
pdf_stream_add_filter (stream, "DCTDecode", NULL);
|
||||
|
||||
/* the following will write the stream, using our callback function to
|
||||
@@ -158,7 +181,13 @@ void pdf_write_jpeg_image (pdf_page_handle pdf_page,
|
||||
& pdf_write_jpeg_content_callback,
|
||||
image));
|
||||
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
|
||||
contents = pdf_get_dict_entry (pdf_page->page_dict, "Contents");
|
||||
|
||||
if (! contents)
|
||||
contents = pdf_new_obj (PT_ARRAY);
|
||||
|
||||
pdf_add_array_elem (contents, content_stream);
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", contents);
|
||||
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2007-05-07 [JDB] Fixed a bug wherein a page label specifying prefix without
|
||||
* a style (e.g., LABEL <prefix>) produced bad PDF (no labels
|
||||
* were displayed). Should have output "/P <prefix>" but
|
||||
* instead output "/S /P <prefix>".
|
||||
*/
|
||||
|
||||
|
||||
@@ -53,10 +58,14 @@ void pdf_new_page_label (pdf_file_handle pdf_file,
|
||||
}
|
||||
|
||||
label_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
pdf_set_dict_entry (label_dict, "S", pdf_new_name (style_str));
|
||||
|
||||
if (style)
|
||||
pdf_set_dict_entry (label_dict, "S", pdf_new_name (style_str));
|
||||
|
||||
if (prefix)
|
||||
pdf_set_dict_entry (label_dict, "P", pdf_new_string (prefix));
|
||||
if (base != 1)
|
||||
|
||||
if (base > 1)
|
||||
pdf_set_dict_entry (label_dict, "St", pdf_new_integer (base));
|
||||
|
||||
pdf_add_number_tree_element (pdf_file->page_label_tree,
|
||||
|
||||
233
pdf_png.c
Normal file
233
pdf_png.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* tumble: build a PDF file from image files
|
||||
*
|
||||
* PDF routines
|
||||
* Copyright 2004 Daniel Gloeckner
|
||||
*
|
||||
* Derived from pdf_jpeg.c written 2003 by Eric Smith <eric at brouhaha.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. Note that permission is
|
||||
* not granted to redistribute this program under the terms of any
|
||||
* other version of the General Public License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2008-12-30 [JDB] Fixed bug wherein "pdf_write_png_content_callback" called
|
||||
* "pdf_stream_printf" to write XObject name without escaping
|
||||
* restricted characters. Now calls "pdf_write_name".
|
||||
*/
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "bitblt.h"
|
||||
#include "pdf.h"
|
||||
#include "pdf_util.h"
|
||||
#include "pdf_prim.h"
|
||||
#include "pdf_private.h"
|
||||
|
||||
|
||||
struct pdf_png_image
|
||||
{
|
||||
double width, height;
|
||||
double x, y;
|
||||
bool color; /* false for grayscale */
|
||||
uint32_t width_samples, height_samples;
|
||||
FILE *f;
|
||||
char XObject_name [4];
|
||||
};
|
||||
|
||||
|
||||
static void pdf_write_png_content_callback (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data)
|
||||
{
|
||||
struct pdf_png_image *image = app_data;
|
||||
|
||||
/* transformation matrix is: width 0 0 height x y cm */
|
||||
pdf_stream_printf (pdf_file, stream, "q %g 0 0 %g %g %g cm ",
|
||||
image->width, image->height,
|
||||
image->x, image->y);
|
||||
pdf_write_name (pdf_file, image->XObject_name);
|
||||
pdf_stream_printf (pdf_file, stream, "Do Q\r\n");
|
||||
}
|
||||
|
||||
|
||||
static void pdf_write_png_image_callback (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data)
|
||||
{
|
||||
struct pdf_png_image *image = app_data;
|
||||
int rlen, wlen;
|
||||
uint8_t *wp;
|
||||
uint8_t buffer [8192];
|
||||
|
||||
while (! feof (image->f))
|
||||
{
|
||||
uint32_t clen;
|
||||
rlen = fread (buffer, 1, 8, image->f);
|
||||
if (rlen != 8)
|
||||
pdf_fatal ("unexpected EOF on input file\n");
|
||||
clen=(buffer[0]<<24)+(buffer[1]<<16)+(buffer[2]<<8)+buffer[3];
|
||||
if (!memcmp(buffer+4,"IEND",4))
|
||||
break;
|
||||
if (memcmp(buffer+4,"IDAT",4)) {
|
||||
fseek(image->f, clen+4, SEEK_CUR);
|
||||
continue;
|
||||
}
|
||||
while (clen)
|
||||
{
|
||||
rlen = fread (buffer, 1, (clen<sizeof(buffer))?clen:sizeof(buffer), image->f);
|
||||
if(!rlen)
|
||||
pdf_fatal ("unexpected EOF on input file\n");
|
||||
clen -= rlen;
|
||||
wp = buffer;
|
||||
while (rlen)
|
||||
{
|
||||
wlen = fwrite (wp, 1, rlen, pdf_file->f);
|
||||
if (feof (pdf_file->f))
|
||||
pdf_fatal ("unexpected EOF on output file\n");
|
||||
if (ferror (pdf_file->f))
|
||||
pdf_fatal ("error on output file\n");
|
||||
rlen -= wlen;
|
||||
wp += wlen;
|
||||
}
|
||||
if (ferror (image->f))
|
||||
pdf_fatal ("error on input file\n");
|
||||
}
|
||||
fseek(image->f, 4, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_png_image (pdf_page_handle pdf_page,
|
||||
double x,
|
||||
double y,
|
||||
double width,
|
||||
double height,
|
||||
int color,
|
||||
char *indexed,
|
||||
int palent,
|
||||
int bpp,
|
||||
uint32_t width_samples,
|
||||
uint32_t height_samples,
|
||||
rgb_range_t *transparency,
|
||||
FILE *f)
|
||||
{
|
||||
struct pdf_png_image *image;
|
||||
|
||||
struct pdf_obj *stream;
|
||||
struct pdf_obj *stream_dict;
|
||||
struct pdf_obj *flateparams;
|
||||
|
||||
struct pdf_obj *content_stream;
|
||||
|
||||
struct pdf_obj *contents;
|
||||
struct pdf_obj *mask;
|
||||
|
||||
image = pdf_calloc (1, sizeof (struct pdf_png_image));
|
||||
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->x = x;
|
||||
image->y = y;
|
||||
|
||||
image->f = f;
|
||||
|
||||
image->color = color;
|
||||
image->width_samples = width_samples;
|
||||
image->height_samples = height_samples;
|
||||
|
||||
pdf_add_array_elem_unique (pdf_page->procset,
|
||||
pdf_new_name (palent ? "ImageI" : image->color ? "ImageC" : "ImageB"));
|
||||
|
||||
stream_dict = pdf_new_obj (PT_DICTIONARY);
|
||||
|
||||
stream = pdf_new_ind_ref (pdf_page->pdf_file,
|
||||
pdf_new_stream (pdf_page->pdf_file,
|
||||
stream_dict,
|
||||
& pdf_write_png_image_callback,
|
||||
image));
|
||||
|
||||
strcpy (& image->XObject_name [0], "Im ");
|
||||
image->XObject_name [2] = pdf_new_XObject (pdf_page, stream);
|
||||
|
||||
flateparams = pdf_new_obj (PT_DICTIONARY);
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "Type", pdf_new_name ("XObject"));
|
||||
pdf_set_dict_entry (stream_dict, "Subtype", pdf_new_name ("Image"));
|
||||
// Name is required in PDF 1.0 but obsoleted in later PDF versions
|
||||
// pdf_set_dict_entry (stream_dict, "Name", pdf_new_name (& image->XObject_name [0]));
|
||||
pdf_set_dict_entry (stream_dict, "Width", pdf_new_integer (image->width_samples));
|
||||
pdf_set_dict_entry (flateparams, "Columns", pdf_new_integer (image->width_samples));
|
||||
pdf_set_dict_entry (stream_dict, "Height", pdf_new_integer (image->height_samples));
|
||||
|
||||
if (transparency)
|
||||
{
|
||||
mask = pdf_new_obj (PT_ARRAY);
|
||||
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->red.first));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->red.last));
|
||||
|
||||
if (!palent && image->color) {
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->green.first));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->green.last));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->blue.first));
|
||||
pdf_add_array_elem (mask, pdf_new_integer (transparency->blue.last));
|
||||
}
|
||||
|
||||
pdf_set_dict_entry (stream_dict, "Mask", mask);
|
||||
}
|
||||
|
||||
if(palent) {
|
||||
struct pdf_obj *space;
|
||||
space = pdf_new_obj (PT_ARRAY);
|
||||
pdf_add_array_elem (space, pdf_new_name ("Indexed"));
|
||||
pdf_add_array_elem (space, pdf_new_name ("DeviceRGB"));
|
||||
pdf_add_array_elem (space, pdf_new_integer (palent-1));
|
||||
pdf_add_array_elem (space, pdf_new_string_n (indexed,3*palent));
|
||||
pdf_set_dict_entry (stream_dict, "ColorSpace", space);
|
||||
} else
|
||||
pdf_set_dict_entry (stream_dict, "ColorSpace", pdf_new_name (image->color ? "DeviceRGB" : "DeviceGray"));
|
||||
|
||||
pdf_set_dict_entry (flateparams, "Colors", pdf_new_integer ((!indexed && image->color) ? 3 : 1));
|
||||
pdf_set_dict_entry (stream_dict, "BitsPerComponent", pdf_new_integer (bpp));
|
||||
pdf_set_dict_entry (flateparams, "BitsPerComponent", pdf_new_integer (bpp));
|
||||
pdf_set_dict_entry (flateparams, "Predictor", pdf_new_integer (15));
|
||||
|
||||
pdf_stream_add_filter (stream, "FlateDecode", flateparams);
|
||||
|
||||
/* the following will write the stream, using our callback function to
|
||||
get the actual data */
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, stream);
|
||||
|
||||
content_stream = pdf_new_ind_ref (pdf_page->pdf_file,
|
||||
pdf_new_stream (pdf_page->pdf_file,
|
||||
pdf_new_obj (PT_DICTIONARY),
|
||||
& pdf_write_png_content_callback,
|
||||
image));
|
||||
|
||||
contents = pdf_get_dict_entry (pdf_page->page_dict, "Contents");
|
||||
|
||||
if (! contents)
|
||||
contents = pdf_new_obj (PT_ARRAY);
|
||||
|
||||
pdf_add_array_elem (contents, content_stream);
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", contents);
|
||||
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
|
||||
}
|
||||
104
pdf_prim.c
104
pdf_prim.c
@@ -19,6 +19,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2007-05-07 [JDB] Allow embedded nulls in strings by storing as character
|
||||
* arrays plus length words.
|
||||
*/
|
||||
|
||||
|
||||
@@ -90,7 +93,10 @@ struct pdf_obj
|
||||
union {
|
||||
bool boolean;
|
||||
char *name;
|
||||
char *string;
|
||||
struct {
|
||||
char *content;
|
||||
int length;
|
||||
} string;
|
||||
long integer;
|
||||
double real;
|
||||
struct pdf_obj *ind_ref;
|
||||
@@ -243,7 +249,18 @@ struct pdf_obj *pdf_new_name (char *name)
|
||||
struct pdf_obj *pdf_new_string (char *str)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_STRING);
|
||||
obj->val.string = pdf_strdup (str);
|
||||
obj->val.string.content = pdf_strdup (str);
|
||||
obj->val.string.length = strlen(str);
|
||||
return (obj);
|
||||
}
|
||||
|
||||
|
||||
struct pdf_obj *pdf_new_string_n (char *str, int n)
|
||||
{
|
||||
struct pdf_obj *obj = pdf_new_obj (PT_STRING);
|
||||
obj->val.string.length = n;
|
||||
obj->val.string.content = pdf_calloc (1,n);
|
||||
memcpy(obj->val.string.content, str, n);
|
||||
return (obj);
|
||||
}
|
||||
|
||||
@@ -397,7 +414,16 @@ int pdf_compare_obj (struct pdf_obj *o1, struct pdf_obj *o2)
|
||||
return (1);
|
||||
return (0);
|
||||
case PT_STRING:
|
||||
return (strcmp (o1->val.string, o2->val.string));
|
||||
{
|
||||
int l;
|
||||
l = o1->val.string.length;
|
||||
if(l > o2->val.string.length)
|
||||
l = o2->val.string.length;
|
||||
l = memcmp (o1->val.string.content, o2->val.string.content, l);
|
||||
if (l)
|
||||
return l;
|
||||
return o1->val.string.length - o2->val.string.length;
|
||||
}
|
||||
case PT_NAME:
|
||||
return (strcmp (o1->val.name, o2->val.name));
|
||||
default:
|
||||
@@ -427,22 +453,70 @@ void pdf_write_name (pdf_file_handle pdf_file, char *s)
|
||||
}
|
||||
|
||||
|
||||
static int string_char_needs_quoting (char c)
|
||||
static int pdf_write_literal_string (pdf_file_handle pdf_file, char *s, int n)
|
||||
{
|
||||
return ((c < ' ') || (c > '~') || (c == '\\') ||
|
||||
(c == '(') || (c == ')'));
|
||||
int i, p;
|
||||
|
||||
if (pdf_file)
|
||||
fprintf (pdf_file->f, "(");
|
||||
|
||||
for (i = p = 0; n; n--)
|
||||
{
|
||||
int j, k;
|
||||
|
||||
k = 0;
|
||||
|
||||
switch (*s)
|
||||
{
|
||||
case '\\':
|
||||
k = 1;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
for (j = k =1; k && j < n; j++)
|
||||
k += (s[j] == '(') ? 1 : (s[j] == ')') ? -1 : 0;
|
||||
p += !k;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
if (p)
|
||||
p--;
|
||||
else
|
||||
k = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (k)
|
||||
{
|
||||
i++;
|
||||
if (pdf_file)
|
||||
fprintf (pdf_file->f, "\\");
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (pdf_file)
|
||||
fprintf (pdf_file->f, "%c", *(s++));
|
||||
}
|
||||
|
||||
if (pdf_file)
|
||||
fprintf (pdf_file->f, ") ");
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
void pdf_write_string (pdf_file_handle pdf_file, char *s)
|
||||
void pdf_write_string (pdf_file_handle pdf_file, char *s, int n)
|
||||
{
|
||||
fprintf (pdf_file->f, "(");
|
||||
while (*s)
|
||||
if (string_char_needs_quoting (*s))
|
||||
fprintf (pdf_file->f, "\\%03o", 0xff & *(s++));
|
||||
else
|
||||
fprintf (pdf_file->f, "%c", *(s++));
|
||||
fprintf (pdf_file->f, ") ");
|
||||
if (pdf_write_literal_string (NULL, s, n) < 2 * n)
|
||||
pdf_write_literal_string (pdf_file, s, n);
|
||||
else
|
||||
{
|
||||
fprintf (pdf_file->f, "<");
|
||||
|
||||
for( ; n--; )
|
||||
fprintf (pdf_file->f, "%.2X",*(s++));
|
||||
fprintf (pdf_file->f, "> ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -560,7 +634,7 @@ void pdf_write_obj (pdf_file_handle pdf_file, struct pdf_obj *obj)
|
||||
pdf_write_name (pdf_file, obj->val.name);
|
||||
break;
|
||||
case PT_STRING:
|
||||
pdf_write_string (pdf_file, obj->val.string);
|
||||
pdf_write_string (pdf_file, obj->val.string.content, obj->val.string.length);
|
||||
break;
|
||||
case PT_INTEGER:
|
||||
fprintf (pdf_file->f, "%ld ", obj->val.integer);
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2007-05-07 [JDB] Add declarations for pdf_new_string_n() and
|
||||
* pdf_write_name().
|
||||
*/
|
||||
|
||||
|
||||
@@ -79,6 +82,8 @@ struct pdf_obj *pdf_new_name (char *name);
|
||||
|
||||
struct pdf_obj *pdf_new_string (char *str);
|
||||
|
||||
struct pdf_obj *pdf_new_string_n (char *str, int n);
|
||||
|
||||
struct pdf_obj *pdf_new_integer (long val);
|
||||
|
||||
struct pdf_obj *pdf_new_real (double val);
|
||||
@@ -146,5 +151,9 @@ void pdf_write_all_ind_obj (pdf_file_handle pdf_file);
|
||||
unsigned long pdf_write_xref (pdf_file_handle pdf_file);
|
||||
|
||||
|
||||
/* Write a name, escaping reserved characters */
|
||||
void pdf_write_name (pdf_file_handle pdf_file, char *s);
|
||||
|
||||
|
||||
/* this isn't really a PDF primitive data type */
|
||||
char pdf_new_XObject (pdf_page_handle pdf_page, struct pdf_obj *ind_ref);
|
||||
|
||||
14
scanner.l
14
scanner.l
@@ -19,10 +19,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*/
|
||||
*
|
||||
* 2009-03-13 [JDB] Add support for blank pages, overlay images, color
|
||||
* mapping, color-key masking, and push/pop of input
|
||||
* contexts.
|
||||
*/
|
||||
|
||||
%option case-insensitive
|
||||
%option noyywrap
|
||||
%option nounput
|
||||
%option noinput
|
||||
|
||||
%{
|
||||
#include <stdbool.h>
|
||||
@@ -46,7 +52,7 @@ dot [\.]
|
||||
|
||||
%%
|
||||
|
||||
[\,;{}] { return (yytext [0]); }
|
||||
[\,;{}()] { return (yytext [0]); }
|
||||
{dot}{dot} { LDBG(("elipsis\n")); return (ELIPSIS); }
|
||||
|
||||
/* decimal integer */
|
||||
@@ -75,8 +81,10 @@ e { yylval.size.width = 34.0;
|
||||
|
||||
all { return (ALL); }
|
||||
author { return (AUTHOR); }
|
||||
blank { return (BLANK); }
|
||||
bookmark { return (BOOKMARK); }
|
||||
cm { return (CM); }
|
||||
colormap { return (COLORMAP); }
|
||||
creator { return (CREATOR); }
|
||||
crop { return (CROP); }
|
||||
even { return (EVEN); }
|
||||
@@ -90,6 +98,7 @@ label { return (LABEL); }
|
||||
landscape { return (LANDSCAPE); }
|
||||
odd { return (ODD); }
|
||||
output { return (OUTPUT); }
|
||||
overlay { return (OVERLAY); }
|
||||
page { return (PAGE); }
|
||||
pages { return (PAGES); }
|
||||
portrait { return (PORTRAIT) ; }
|
||||
@@ -98,6 +107,7 @@ rotate { return (ROTATE); }
|
||||
size { return (SIZE); }
|
||||
subject { return (SUBJECT); }
|
||||
title { return (TITLE); }
|
||||
transparent { return (TRANSPARENT); }
|
||||
|
||||
'[^\n']' {
|
||||
yylval.character = yytext [1];
|
||||
|
||||
131
semantics.c
131
semantics.c
@@ -19,6 +19,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-13 [JDB] Add support for blank pages, overlay images, color
|
||||
* mapping, color-key masking, and push/pop of input
|
||||
* contexts.
|
||||
*/
|
||||
|
||||
|
||||
@@ -47,6 +51,9 @@ typedef struct
|
||||
|
||||
bool has_crop;
|
||||
crop_t crop;
|
||||
|
||||
bool has_transparency;
|
||||
rgb_range_t transparency;
|
||||
} input_modifiers_t;
|
||||
|
||||
|
||||
@@ -59,6 +66,7 @@ typedef struct input_context_t
|
||||
including those from subcontexts */
|
||||
|
||||
char *input_file;
|
||||
bool is_blank;
|
||||
|
||||
input_modifiers_t modifiers [INPUT_MODIFIER_TYPE_COUNT];
|
||||
} input_context_t;
|
||||
@@ -88,6 +96,9 @@ typedef struct output_context_t
|
||||
|
||||
bool has_page_label;
|
||||
page_label_t page_label;
|
||||
|
||||
bool has_colormap;
|
||||
colormap_t colormap;
|
||||
} output_context_t;
|
||||
|
||||
|
||||
@@ -97,11 +108,11 @@ typedef struct output_page_t
|
||||
output_context_t *output_context;
|
||||
range_t range;
|
||||
bookmark_t *bookmark_list;
|
||||
bool has_overlay;
|
||||
overlay_t overlay;
|
||||
} output_page_t;
|
||||
|
||||
|
||||
#undef SEMANTIC_DEBUG
|
||||
|
||||
#ifdef SEMANTIC_DEBUG
|
||||
#define SDBG(x) printf x
|
||||
#else
|
||||
@@ -117,7 +128,7 @@ int bookmark_level;
|
||||
input_context_t *first_input_context;
|
||||
input_context_t *last_input_context;
|
||||
|
||||
input_modifier_type_t current_modifier_context;
|
||||
input_modifier_type_t current_modifier_context = INPUT_MODIFIER_ALL;
|
||||
|
||||
input_image_t *first_input_image;
|
||||
input_image_t *last_input_image;
|
||||
@@ -206,6 +217,7 @@ void input_set_file (char *name)
|
||||
{
|
||||
input_clone ();
|
||||
last_input_context->input_file = name;
|
||||
last_input_context->is_blank = (name == NULL);
|
||||
};
|
||||
|
||||
void input_set_rotation (int rotation)
|
||||
@@ -222,6 +234,12 @@ void input_set_page_size (page_size_t size)
|
||||
SDBG(("page size %f, %f\n", size.width, size.height));
|
||||
}
|
||||
|
||||
void input_set_transparency (rgb_range_t rgb_range)
|
||||
{
|
||||
last_input_context->modifiers [current_modifier_context].has_transparency = 1;
|
||||
last_input_context->modifiers [current_modifier_context].transparency = rgb_range;
|
||||
}
|
||||
|
||||
static void increment_input_image_count (int count)
|
||||
{
|
||||
input_context_t *context;
|
||||
@@ -446,16 +464,31 @@ void output_pages (range_t range)
|
||||
}
|
||||
|
||||
|
||||
void output_overlay (overlay_t overlay)
|
||||
{
|
||||
output_pages (last_output_page->range);
|
||||
last_output_page->has_overlay = 1;
|
||||
last_output_page->overlay.left = overlay.left;
|
||||
last_output_page->overlay.top = overlay.top;
|
||||
}
|
||||
|
||||
void output_set_colormap (rgb_t black_color, rgb_t white_color)
|
||||
{
|
||||
output_clone ();
|
||||
last_output_context->has_colormap = 1;
|
||||
last_output_context->colormap.black_map = black_color;
|
||||
last_output_context->colormap.white_map = white_color;
|
||||
}
|
||||
|
||||
void yyerror (char *s)
|
||||
{
|
||||
fprintf (stderr, "%d: %s\n", line, s);
|
||||
}
|
||||
|
||||
|
||||
static char *get_input_filename (input_context_t *context)
|
||||
{
|
||||
for (; context; context = context->parent)
|
||||
if (context->input_file)
|
||||
if ((context->input_file) || (context->is_blank))
|
||||
return (context->input_file);
|
||||
fprintf (stderr, "no input file name found\n");
|
||||
exit (2);
|
||||
@@ -481,6 +514,23 @@ static bool get_input_rotation (input_context_t *context,
|
||||
return (0); /* default */
|
||||
}
|
||||
|
||||
static rgb_range_t *get_input_transparency (input_context_t *context,
|
||||
input_modifier_type_t type)
|
||||
{
|
||||
for (; context; context = context->parent)
|
||||
{
|
||||
if (context->modifiers [type].has_transparency)
|
||||
{
|
||||
return & (context->modifiers [type].transparency);
|
||||
}
|
||||
if (context->modifiers [INPUT_MODIFIER_ALL].has_transparency)
|
||||
{
|
||||
return & (context->modifiers [INPUT_MODIFIER_ALL].transparency);
|
||||
}
|
||||
}
|
||||
return NULL; /* default */
|
||||
}
|
||||
|
||||
static bool get_input_page_size (input_context_t *context,
|
||||
input_modifier_type_t type,
|
||||
page_size_t *page_size)
|
||||
@@ -527,12 +577,21 @@ static page_label_t *get_output_page_label (output_context_t *context)
|
||||
return (NULL); /* default */
|
||||
}
|
||||
|
||||
static colormap_t *get_output_colormap (output_context_t *context)
|
||||
{
|
||||
for (; context; context = context->parent)
|
||||
if (context->has_colormap)
|
||||
return (& context->colormap);
|
||||
return (NULL); /* default */
|
||||
}
|
||||
|
||||
|
||||
#ifdef SEMANTIC_DEBUG
|
||||
void dump_input_tree (void)
|
||||
{
|
||||
input_image_t *image;
|
||||
int i;
|
||||
char *fn;
|
||||
|
||||
printf ("input images:\n");
|
||||
for (image = first_input_image; image; image = image->next)
|
||||
@@ -542,6 +601,7 @@ void dump_input_tree (void)
|
||||
bool has_rotation, has_page_size;
|
||||
int rotation;
|
||||
page_size_t page_size;
|
||||
rgb_range_t *transparency;
|
||||
|
||||
has_rotation = get_input_rotation (image->input_context,
|
||||
parity,
|
||||
@@ -549,11 +609,19 @@ void dump_input_tree (void)
|
||||
has_page_size = get_input_page_size (image->input_context,
|
||||
parity,
|
||||
& page_size);
|
||||
printf ("file '%s' image %d",
|
||||
get_input_filename (image->input_context),
|
||||
i);
|
||||
transparency = get_input_transparency (image->input_context, parity);
|
||||
fn = get_input_filename (image->input_context);
|
||||
if (fn)
|
||||
printf ("file '%s' image %d", fn, i);
|
||||
else
|
||||
printf ("blank image %d", i);
|
||||
if (has_rotation)
|
||||
printf (" rotation %d", rotation);
|
||||
if (transparency)
|
||||
printf (" transparency %d..%d, %d..%d, %d..%d",
|
||||
transparency->red.first, transparency->red.last,
|
||||
transparency->green.first, transparency->green.last,
|
||||
transparency->blue.first, transparency->blue.last);
|
||||
if (has_page_size)
|
||||
printf (" size %f, %f", page_size.width, page_size.height);
|
||||
printf ("\n");
|
||||
@@ -578,6 +646,7 @@ void dump_output_tree (void)
|
||||
for (i = page->range.first; i <= page->range.last; i++)
|
||||
{
|
||||
page_label_t *label = get_output_page_label (page->output_context);
|
||||
colormap_t *colormap = get_output_colormap (page->output_context);
|
||||
printf ("file \"%s\" ", get_output_filename (page->output_context));
|
||||
if (label)
|
||||
{
|
||||
@@ -587,6 +656,10 @@ void dump_output_tree (void)
|
||||
if (label->style)
|
||||
printf ("'%c' ", label->style);
|
||||
}
|
||||
if (colormap)
|
||||
printf ("colormap (%d %d %d) (%d %d %d) ",
|
||||
colormap->black_map.red, colormap->black_map.green, colormap->black_map.blue,
|
||||
colormap->white_map.red, colormap->white_map.green, colormap->white_map.blue);
|
||||
printf ("page %d\n", i);
|
||||
}
|
||||
}
|
||||
@@ -630,7 +703,7 @@ bool parse_control_file (char *fn)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fprintf (stderr, "%d pages specified\n", first_input_context->image_count);
|
||||
fprintf (stderr, "%d images specified\n", first_input_context->image_count);
|
||||
|
||||
result = 1;
|
||||
|
||||
@@ -646,6 +719,22 @@ bool parse_control_file (char *fn)
|
||||
return (result);
|
||||
}
|
||||
|
||||
bool omit_label (page_label_t *page_label)
|
||||
{
|
||||
static page_label_t *last_page_label;
|
||||
bool unneeded;
|
||||
|
||||
unneeded = ( (last_page_label != NULL) &&
|
||||
page_label->prefix &&
|
||||
last_page_label->prefix &&
|
||||
(strcmp (page_label->prefix, last_page_label->prefix) == 0) &&
|
||||
(page_label->style == last_page_label->style) &&
|
||||
(page_label->base == last_page_label->base + 1) );
|
||||
|
||||
last_page_label = page_label;
|
||||
|
||||
return unneeded;
|
||||
}
|
||||
|
||||
bool process_controls (void)
|
||||
{
|
||||
@@ -672,7 +761,12 @@ bool process_controls (void)
|
||||
i = 0;
|
||||
input_fn = get_input_filename (image->input_context);
|
||||
if (verbose)
|
||||
fprintf (stderr, "opening input file '%s'\n", input_fn);
|
||||
{
|
||||
if (input_fn)
|
||||
fprintf (stderr, "opening input file '%s'\n", input_fn);
|
||||
else
|
||||
fprintf (stderr, "generating blank image\n");
|
||||
}
|
||||
if (! open_input_file (input_fn))
|
||||
{
|
||||
fprintf (stderr, "error opening input file '%s'\n", input_fn);
|
||||
@@ -712,6 +806,12 @@ bool process_controls (void)
|
||||
parity,
|
||||
& input_attributes.page_size);
|
||||
|
||||
input_attributes.transparency = get_input_transparency (image->input_context, parity);
|
||||
|
||||
|
||||
// really an output attribute, but we don't have such an thing
|
||||
input_attributes.colormap = get_output_colormap (page->output_context);
|
||||
|
||||
if (verbose)
|
||||
fprintf (stderr, "processing image %d\n", image->range.first + i);
|
||||
|
||||
@@ -725,20 +825,27 @@ bool process_controls (void)
|
||||
page_label->page_index = page_index;
|
||||
page_label->base = page->range.first;
|
||||
page_label->count = range_count (page->range);
|
||||
|
||||
if (omit_label (page_label))
|
||||
page_label = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (! process_page (image->range.first + i,
|
||||
input_attributes,
|
||||
p ? NULL : page->bookmark_list,
|
||||
page_label))
|
||||
page_label,
|
||||
page->has_overlay ? & page->overlay : NULL,
|
||||
input_attributes.transparency))
|
||||
{
|
||||
fprintf (stderr, "error processing image %d\n", image->range.first + i);
|
||||
return (0);
|
||||
}
|
||||
i++;
|
||||
p++;
|
||||
page_index++;
|
||||
|
||||
if (! page->has_overlay)
|
||||
page_index++;
|
||||
}
|
||||
}
|
||||
#endif /* CTL_LANG */
|
||||
|
||||
60
semantics.h
60
semantics.h
@@ -19,14 +19,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-13 [JDB] Add support for blank pages, overlay images, color
|
||||
* mapping, color-key masking, and push/pop of input
|
||||
* contexts.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double width;
|
||||
double height;
|
||||
} page_size_t;
|
||||
// HACK! rgb_t and colormap_t have to appear here and in pdf_g4! See pdf.h
|
||||
#define SEMANTICS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -34,6 +34,46 @@ typedef struct
|
||||
int last;
|
||||
} range_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int red;
|
||||
int green;
|
||||
int blue;
|
||||
} rgb_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
range_t red;
|
||||
range_t green;
|
||||
range_t blue;
|
||||
} rgb_range_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rgb_t black_map;
|
||||
rgb_t white_map;
|
||||
} colormap_t;
|
||||
|
||||
// end of HACK
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
} position_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double left;
|
||||
double top;
|
||||
} overlay_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double width;
|
||||
double height;
|
||||
} page_size_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double left;
|
||||
@@ -74,12 +114,17 @@ extern int line; /* line number in spec file */
|
||||
extern int bookmark_level;
|
||||
|
||||
|
||||
/* Bison interface */
|
||||
extern int yyparse (void);
|
||||
void yyerror (char *s);
|
||||
|
||||
/* semantic routines for input statements */
|
||||
void input_push_context (void);
|
||||
void input_pop_context (void);
|
||||
void input_set_modifier_context (input_modifier_type_t type);
|
||||
void input_set_file (char *name);
|
||||
void input_set_rotation (int rotation);
|
||||
void input_set_transparency (rgb_range_t rgb_range);
|
||||
void input_set_page_size (page_size_t size);
|
||||
void input_images (range_t range);
|
||||
|
||||
@@ -97,6 +142,9 @@ void output_set_keywords (char *keywords);
|
||||
void output_set_bookmark (char *name);
|
||||
void output_set_page_label (page_label_t label);
|
||||
void output_pages (range_t range);
|
||||
void output_overlay (overlay_t overlay);
|
||||
void output_transparency (rgb_range_t rgb_range);
|
||||
void output_set_colormap (rgb_t black_color, rgb_t white_color);
|
||||
|
||||
|
||||
/* functions to be called from main program: */
|
||||
|
||||
62
tumble.c
62
tumble.c
@@ -19,6 +19,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-02 [JDB] Add support for overlay images and color key masking.
|
||||
* 2014-02-18 [JDB] Add -V option to print the program version.
|
||||
*/
|
||||
|
||||
|
||||
@@ -53,7 +56,7 @@ typedef struct output_file_t
|
||||
} output_file_t;
|
||||
|
||||
|
||||
int verbose;
|
||||
int verbose, version;
|
||||
|
||||
|
||||
output_file_t *output_files;
|
||||
@@ -81,9 +84,11 @@ void usage (void)
|
||||
fprintf (stderr, " %s [options] -c <control.tum>\n", progname);
|
||||
#endif
|
||||
fprintf (stderr, " %s [options] <input.tif>... -o <output.pdf>\n", progname);
|
||||
fprintf (stderr, " %s -V\n", progname);
|
||||
fprintf (stderr, "options:\n");
|
||||
fprintf (stderr, " -v verbose\n");
|
||||
fprintf (stderr, " -b <fmt> create bookmarks\n");
|
||||
fprintf (stderr, " -V print program version\n");
|
||||
fprintf (stderr, "bookmark format:\n");
|
||||
fprintf (stderr, " %%F file name (sans suffix)\n");
|
||||
fprintf (stderr, " %%p page number\n");
|
||||
@@ -191,25 +196,54 @@ bool open_pdf_output_file (char *name,
|
||||
#define MAX_BOOKMARK_LEVEL 20
|
||||
static pdf_bookmark_handle bookmark_vector [MAX_BOOKMARK_LEVEL + 1] = { NULL };
|
||||
|
||||
static pdf_page_handle last_page = NULL;
|
||||
static page_size_t last_size;
|
||||
|
||||
bool process_page (int image, /* range 1 .. n */
|
||||
input_attributes_t input_attributes,
|
||||
bookmark_t *bookmarks,
|
||||
page_label_t *page_label)
|
||||
page_label_t *page_label,
|
||||
overlay_t *overlay,
|
||||
rgb_range_t *transparency)
|
||||
{
|
||||
pdf_page_handle page;
|
||||
image_info_t image_info;
|
||||
position_t position;
|
||||
|
||||
if (! get_image_info (image, input_attributes, & image_info))
|
||||
return (0);
|
||||
|
||||
page = pdf_new_page (out->pdf,
|
||||
image_info.width_points,
|
||||
image_info.height_points);
|
||||
if (overlay)
|
||||
{
|
||||
page = last_page;
|
||||
position.x = overlay->left * POINTS_PER_INCH;
|
||||
position.y = last_size.height - image_info.height_points - overlay->top * POINTS_PER_INCH;
|
||||
|
||||
if (! process_image (image, input_attributes, & image_info, page))
|
||||
if (verbose)
|
||||
fprintf (stderr, "overlaying image at %.3f, %.3f\n", position.x, position.y);
|
||||
|
||||
if (transparency)
|
||||
{
|
||||
input_attributes.transparency = transparency;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last_page = page = pdf_new_page (out->pdf,
|
||||
image_info.width_points,
|
||||
image_info.height_points);
|
||||
last_size.width = image_info.width_points;
|
||||
last_size.height = image_info.height_points;
|
||||
position.x = 0.0;
|
||||
position.y = 0.0;
|
||||
}
|
||||
|
||||
if (! process_image (image, input_attributes, & image_info, page, position))
|
||||
return (0);
|
||||
|
||||
if (overlay)
|
||||
return (page != NULL);
|
||||
|
||||
while (bookmarks)
|
||||
{
|
||||
if (bookmarks->level <= MAX_BOOKMARK_LEVEL)
|
||||
@@ -338,6 +372,8 @@ void main_args (char *out_fn,
|
||||
ip);
|
||||
if (! process_page (ip, input_attributes,
|
||||
bookmark_fmt ? & bookmark : NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL))
|
||||
fatal (3, "error processing page %d of input file \"%s\"\n", ip, in_fn [i]);
|
||||
if (last_input_page ())
|
||||
@@ -381,12 +417,18 @@ int main (int argc, char *argv[])
|
||||
init_tiff_handler ();
|
||||
init_jpeg_handler ();
|
||||
init_pbm_handler ();
|
||||
init_png_handler ();
|
||||
|
||||
while (--argc)
|
||||
{
|
||||
if (argv [1][0] == '-')
|
||||
{
|
||||
if (strcmp (argv [1], "-v") == 0)
|
||||
if (strcmp (argv [1], "-V") == 0)
|
||||
{
|
||||
version++;
|
||||
break;
|
||||
}
|
||||
else if (strcmp (argv [1], "-v") == 0)
|
||||
verbose++;
|
||||
else if (strcmp (argv [1], "-o") == 0)
|
||||
{
|
||||
@@ -433,6 +475,12 @@ int main (int argc, char *argv[])
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (version)
|
||||
{
|
||||
puts (PDF_PRODUCER);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#ifdef CTL_LANG
|
||||
if (! ((! out_fn) ^ (! control_fn)))
|
||||
fatal (1, "either a control file or an output file (but not both) must be specified\n");
|
||||
|
||||
11
tumble.h
11
tumble.h
@@ -18,6 +18,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-02 [JDB] Add support for overlay images and color key masking.
|
||||
*/
|
||||
|
||||
|
||||
@@ -38,6 +40,11 @@ typedef struct
|
||||
|
||||
bool has_crop;
|
||||
crop_t crop;
|
||||
|
||||
rgb_range_t *transparency;
|
||||
|
||||
colormap_t *colormap; // really an output attribute, but we don't have such a thing
|
||||
|
||||
} input_attributes_t;
|
||||
|
||||
|
||||
@@ -61,4 +68,6 @@ bool open_pdf_output_file (char *name,
|
||||
bool process_page (int image, /* range 1 .. n */
|
||||
input_attributes_t input_attributes,
|
||||
bookmark_t *bookmarks,
|
||||
page_label_t *page_label);
|
||||
page_label_t *page_label,
|
||||
overlay_t *overlay,
|
||||
rgb_range_t *transparency);
|
||||
|
||||
149
tumble_blank.c
Normal file
149
tumble_blank.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* tumble: build a PDF file from image files
|
||||
*
|
||||
* $Id: tumble_blank.c ... Exp $
|
||||
* Copyright ...
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. Note that permission is
|
||||
* not granted to redistribute this program under the terms of any
|
||||
* other version of the General Public License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2007-05-07 [JDB] New file to add support for blank pages.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "semantics.h"
|
||||
#include "tumble.h"
|
||||
#include "bitblt.h"
|
||||
#include "pdf.h"
|
||||
#include "pdf_util.h"
|
||||
#include "pdf_prim.h"
|
||||
#include "pdf_private.h"
|
||||
#include "tumble_input.h"
|
||||
|
||||
|
||||
struct pdf_blank_page
|
||||
{
|
||||
double width;
|
||||
double height;
|
||||
double x;
|
||||
double y;
|
||||
double red;
|
||||
double green;
|
||||
double blue;
|
||||
};
|
||||
|
||||
|
||||
static bool match_blank_suffix (char *suffix)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool close_blank_input_file (void)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static bool open_blank_input_file (FILE *f, char *name)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static bool last_blank_input_page (void)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
static bool get_blank_image_info (int image,
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info)
|
||||
{
|
||||
if (input_attributes.has_page_size)
|
||||
{
|
||||
image_info->width_points = input_attributes.page_size.width * POINTS_PER_INCH;
|
||||
image_info->height_points = input_attributes.page_size.height * POINTS_PER_INCH;
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static void pdf_write_blank_content_callback (pdf_file_handle pdf_file,
|
||||
struct pdf_obj *stream,
|
||||
void *app_data)
|
||||
{
|
||||
struct pdf_blank_page *page = app_data;
|
||||
|
||||
pdf_stream_printf (pdf_file, stream,
|
||||
"%g %g %g rg\r\n%g %g %g %g re\r\nf\r\n",
|
||||
page->red, page->green, page->blue,
|
||||
page->x, page->y,
|
||||
page->width, page->height);
|
||||
}
|
||||
|
||||
|
||||
static bool process_blank_image (int image, /* range 1 .. n */
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle pdf_page,
|
||||
position_t position)
|
||||
{
|
||||
struct pdf_blank_page *page;
|
||||
struct pdf_obj *content_stream;
|
||||
|
||||
/* If colormap set, use "white" color and draw rectangle to cover page. */
|
||||
|
||||
if (input_attributes.colormap)
|
||||
{
|
||||
page = pdf_calloc (1, sizeof (struct pdf_blank_page));
|
||||
|
||||
page->width = image_info->width_points;
|
||||
page->height = image_info->height_points;
|
||||
page->x = 0;
|
||||
page->y = 0;
|
||||
page->red = (double) input_attributes.colormap->white_map.red / 255.0;
|
||||
page->green = (double) input_attributes.colormap->white_map.green / 255.0;
|
||||
page->blue = (double) input_attributes.colormap->white_map.blue / 255.0;
|
||||
|
||||
content_stream = pdf_new_ind_ref (pdf_page->pdf_file,
|
||||
pdf_new_stream (pdf_page->pdf_file,
|
||||
pdf_new_obj (PT_DICTIONARY),
|
||||
& pdf_write_blank_content_callback,
|
||||
page));
|
||||
|
||||
pdf_set_dict_entry (pdf_page->page_dict, "Contents", content_stream);
|
||||
pdf_write_ind_obj (pdf_page->pdf_file, content_stream);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
input_handler_t blank_handler =
|
||||
{
|
||||
match_blank_suffix,
|
||||
open_blank_input_file,
|
||||
close_blank_input_file,
|
||||
last_blank_input_page,
|
||||
get_blank_image_info,
|
||||
process_blank_image
|
||||
};
|
||||
@@ -19,6 +19,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2007-05-07 [JDB] Add support for blank pages and fix a bug that caused a
|
||||
* double free.
|
||||
*/
|
||||
|
||||
|
||||
@@ -66,10 +69,19 @@ bool match_input_suffix (char *suffix)
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
bool open_input_file (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
if (in)
|
||||
close_input_file ();
|
||||
current_input_handler = & blank_handler;
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (in)
|
||||
{
|
||||
if (strcmp (name, in_filename) == 0)
|
||||
@@ -117,8 +129,10 @@ bool close_input_file (void)
|
||||
result = current_input_handler->close_input_file ();
|
||||
current_input_handler = NULL;
|
||||
}
|
||||
if (in_filename)
|
||||
if (in_filename) {
|
||||
free (in_filename);
|
||||
in_filename = NULL;
|
||||
}
|
||||
if (in)
|
||||
{
|
||||
fclose (in);
|
||||
@@ -151,12 +165,14 @@ bool get_image_info (int image,
|
||||
bool process_image (int image,
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle page)
|
||||
pdf_page_handle page,
|
||||
position_t position)
|
||||
{
|
||||
if (! current_input_handler)
|
||||
return (0);
|
||||
return (current_input_handler->process_image (image,
|
||||
input_attributes,
|
||||
image_info,
|
||||
page));
|
||||
page,
|
||||
position));
|
||||
}
|
||||
|
||||
@@ -18,12 +18,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2010-09-02 [JDB] Added support for min-is-black TIFF images.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool color;
|
||||
bool negative;
|
||||
uint32_t width_samples, height_samples;
|
||||
double width_points, height_points;
|
||||
double x_resolution, y_resolution;
|
||||
@@ -42,7 +45,8 @@ typedef struct
|
||||
bool (*process_image) (int image,
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle page);
|
||||
pdf_page_handle page,
|
||||
position_t position);
|
||||
} input_handler_t;
|
||||
|
||||
|
||||
@@ -59,9 +63,13 @@ bool get_image_info (int image,
|
||||
bool process_image (int image,
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle page);
|
||||
pdf_page_handle page,
|
||||
position_t position);
|
||||
|
||||
|
||||
void init_tiff_handler (void);
|
||||
void init_jpeg_handler (void);
|
||||
void init_pbm_handler (void);
|
||||
void init_png_handler (void);
|
||||
|
||||
input_handler_t blank_handler;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-02 [JDB] Add support for overlay images.
|
||||
*/
|
||||
|
||||
|
||||
@@ -165,15 +167,17 @@ static bool get_jpeg_image_info (int image,
|
||||
static bool process_jpeg_image (int image, /* range 1 .. n */
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle page)
|
||||
pdf_page_handle page,
|
||||
position_t position)
|
||||
{
|
||||
pdf_write_jpeg_image (page,
|
||||
0, 0, /* x, y */
|
||||
position.x, position.y,
|
||||
image_info->width_points,
|
||||
image_info->height_points,
|
||||
image_info->color,
|
||||
image_info->width_samples,
|
||||
image_info->height_samples,
|
||||
input_attributes.transparency,
|
||||
jpeg_f);
|
||||
|
||||
return (1);
|
||||
|
||||
15
tumble_pbm.c
15
tumble_pbm.c
@@ -18,6 +18,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-02 [JDB] Add support for overlay images.
|
||||
*/
|
||||
|
||||
|
||||
@@ -125,6 +127,8 @@ static bool get_pbm_image_info (int image,
|
||||
return (0);
|
||||
}
|
||||
|
||||
image_info->negative = false;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -132,7 +136,8 @@ static bool get_pbm_image_info (int image,
|
||||
static bool process_pbm_image (int image, /* range 1 .. n */
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle page)
|
||||
pdf_page_handle page,
|
||||
position_t position)
|
||||
{
|
||||
bool result = 0;
|
||||
Rect rect;
|
||||
@@ -192,12 +197,12 @@ static bool process_pbm_image (int image, /* range 1 .. n */
|
||||
#endif
|
||||
|
||||
pdf_write_g4_fax_image (page,
|
||||
0, 0, /* x, y */
|
||||
position.x, position.y,
|
||||
image_info->width_points, image_info->height_points,
|
||||
image_info->negative,
|
||||
bitmap,
|
||||
0, /* ImageMask */
|
||||
0, 0, 0, /* r, g, b */
|
||||
0); /* BlackIs1 */
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
result = 1;
|
||||
|
||||
|
||||
237
tumble_png.c
Normal file
237
tumble_png.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* tumble: build a PDF file from image files
|
||||
*
|
||||
* Copyright 2004 Daniel Gloeckner
|
||||
*
|
||||
* Derived from tumble_jpeg.c written 2003 by Eric Smith <eric at brouhaha.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. Note that permission is
|
||||
* not granted to redistribute this program under the terms of any
|
||||
* other version of the General Public License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2009-03-13 [JDB] New module to add PNG image support.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h> /* strcasecmp() is a BSDism */
|
||||
|
||||
|
||||
#include "semantics.h"
|
||||
#include "tumble.h"
|
||||
#include "bitblt.h"
|
||||
#include "pdf.h"
|
||||
#include "tumble_input.h"
|
||||
|
||||
|
||||
static FILE *png_f;
|
||||
|
||||
static struct {
|
||||
uint32_t palent;
|
||||
uint8_t bpp;
|
||||
uint8_t color;
|
||||
char pal[256*3];
|
||||
} cinfo;
|
||||
|
||||
|
||||
static bool match_png_suffix (char *suffix)
|
||||
{
|
||||
return (strcasecmp (suffix, ".png") == 0);
|
||||
}
|
||||
|
||||
static bool close_png_input_file (void)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
#define BENUM(p) (((p)[0]<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3])
|
||||
|
||||
static bool open_png_input_file (FILE *f, char *name)
|
||||
{
|
||||
const char sig [8]="\211PNG\r\n\032\n";
|
||||
uint8_t buf [8];
|
||||
int l;
|
||||
|
||||
l = fread (buf, 1, sizeof (sig), f);
|
||||
if (l != sizeof (sig) || memcmp(buf,sig,sizeof(sig))) {
|
||||
rewind(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
png_f = f;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static bool last_png_input_page (void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static bool get_png_image_info (int image,
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info)
|
||||
{
|
||||
uint8_t buf [20], unit;
|
||||
uint32_t width,height,xppu,yppu;
|
||||
size_t l;
|
||||
bool seen_IHDR,seen_PLTE,seen_pHYs;
|
||||
|
||||
seen_IHDR=seen_PLTE=seen_pHYs=false;
|
||||
memset(&cinfo,0,sizeof(cinfo));
|
||||
unit=0;
|
||||
xppu=yppu=1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
l = fread (buf, 1, 8, png_f);
|
||||
if(l != 8)
|
||||
return 0;
|
||||
l=BENUM(buf);
|
||||
if(!memcmp(buf+4,"IHDR",4)) {
|
||||
if(seen_IHDR || l!=13)
|
||||
return 0;
|
||||
seen_IHDR=true;
|
||||
l = fread (buf, 1, 17, png_f);
|
||||
if(l!=17)
|
||||
return 0;
|
||||
width=BENUM(buf);
|
||||
height=BENUM(buf+4);
|
||||
cinfo.bpp=buf[8];
|
||||
cinfo.color=buf[9];
|
||||
if(buf[8]>8 || buf[10] || buf[11] || buf[12])
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
if(!seen_IHDR)
|
||||
return 0;
|
||||
if(!memcmp(buf+4,"PLTE",4)) {
|
||||
size_t i;
|
||||
if(seen_PLTE || l>256*3 || l%3 || !cinfo.color)
|
||||
return 0;
|
||||
seen_PLTE=true;
|
||||
i = fread (cinfo.pal, 1, l, png_f);
|
||||
if(i != l)
|
||||
return 0;
|
||||
cinfo.palent=l/3;
|
||||
fseek(png_f,4,SEEK_CUR);
|
||||
} else if(!memcmp(buf+4,"pHYs",4)) {
|
||||
if(seen_pHYs || l!=9)
|
||||
return 0;
|
||||
seen_pHYs=true;
|
||||
l = fread (buf, 1, 13, png_f);
|
||||
if(l != 13)
|
||||
return 0;
|
||||
xppu=BENUM(buf);
|
||||
yppu=BENUM(buf+4);
|
||||
unit=buf[8];
|
||||
} else if(!memcmp(buf+4,"IDAT",4)) {
|
||||
fseek(png_f,-8,SEEK_CUR);
|
||||
break;
|
||||
} else {
|
||||
fseek(png_f,l+4,SEEK_CUR);
|
||||
}
|
||||
}
|
||||
if(cinfo.color==3 && !seen_PLTE)
|
||||
return 0;
|
||||
|
||||
#ifdef DEBUG_JPEG
|
||||
printf ("color type: %d\n", cinfo.color);
|
||||
printf ("bit depth: %d\n", cinfo.bpp);
|
||||
printf ("density unit: %d\n", unit);
|
||||
printf ("x density: %d\n", xppu);
|
||||
printf ("y density: %d\n", yppu);
|
||||
printf ("width: %d\n", width);
|
||||
printf ("height: %d\n", height);
|
||||
#endif
|
||||
|
||||
switch (cinfo.color)
|
||||
{
|
||||
case 0:
|
||||
image_info->color = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
image_info->color = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "PNG color type %d not supported\n", cinfo.color);
|
||||
return (0);
|
||||
}
|
||||
image_info->width_samples = width;
|
||||
image_info->height_samples = height;
|
||||
|
||||
switch (unit==1)
|
||||
{
|
||||
case 1:
|
||||
image_info->width_points = ((image_info->width_samples * POINTS_PER_INCH) /
|
||||
(xppu * 0.0254));
|
||||
image_info->height_points = ((image_info->height_samples * POINTS_PER_INCH) /
|
||||
(yppu * 0.0254));
|
||||
break;
|
||||
case 0:
|
||||
/* assume 300 DPI - not great, but what else can we do? */
|
||||
image_info->width_points = (image_info->width_samples * POINTS_PER_INCH) / 300.0;
|
||||
image_info->height_points = ((double) yppu * image_info->height_samples * POINTS_PER_INCH) / ( 300.0 * xppu);
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "PNG pHYs unit %d not supported\n", unit);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static bool process_png_image (int image, /* range 1 .. n */
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle page,
|
||||
position_t position)
|
||||
{
|
||||
pdf_write_png_image (page,
|
||||
position.x, position.y,
|
||||
image_info->width_points,
|
||||
image_info->height_points,
|
||||
cinfo.color,
|
||||
cinfo.color==3?cinfo.pal:NULL,
|
||||
cinfo.palent,
|
||||
cinfo.bpp,
|
||||
image_info->width_samples,
|
||||
image_info->height_samples,
|
||||
input_attributes.transparency,
|
||||
png_f);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
input_handler_t png_handler =
|
||||
{
|
||||
match_png_suffix,
|
||||
open_png_input_file,
|
||||
close_png_input_file,
|
||||
last_png_input_page,
|
||||
get_png_image_info,
|
||||
process_png_image
|
||||
};
|
||||
|
||||
|
||||
void init_png_handler (void)
|
||||
{
|
||||
install_input_handler (& png_handler);
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
|
||||
*
|
||||
* 2010-09-02 [JDB] Added support for min-is-black TIFF images.
|
||||
*/
|
||||
|
||||
|
||||
@@ -102,6 +104,7 @@ static bool get_tiff_image_info (int image,
|
||||
uint32_t image_height, image_width;
|
||||
uint16_t samples_per_pixel;
|
||||
uint16_t bits_per_sample;
|
||||
uint16_t photometric_interpretation;
|
||||
uint16_t planar_config;
|
||||
|
||||
uint16_t resolution_unit;
|
||||
@@ -149,6 +152,19 @@ static bool get_tiff_image_info (int image,
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (1 != TIFFGetField (tiff_in, TIFFTAG_PHOTOMETRIC, & photometric_interpretation))
|
||||
{
|
||||
fprintf(stderr, "warning: photometric interpretation not specified, assuming min-is-white\n");
|
||||
photometric_interpretation = PHOTOMETRIC_MINISWHITE;
|
||||
}
|
||||
|
||||
else if ((photometric_interpretation != PHOTOMETRIC_MINISWHITE) &&
|
||||
(photometric_interpretation != PHOTOMETRIC_MINISBLACK))
|
||||
{
|
||||
fprintf(stderr, "photometric interpretation value %u is invalid\n", photometric_interpretation);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (1 != TIFFGetField (tiff_in, TIFFTAG_PLANARCONFIG, & planar_config))
|
||||
planar_config = 1;
|
||||
|
||||
@@ -217,6 +233,8 @@ static bool get_tiff_image_info (int image,
|
||||
return (0);
|
||||
}
|
||||
|
||||
image_info->negative = (photometric_interpretation == PHOTOMETRIC_MINISBLACK);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -267,7 +285,8 @@ static void rotate_bitmap (Bitmap *src,
|
||||
static bool process_tiff_image (int image, /* range 1 .. n */
|
||||
input_attributes_t input_attributes,
|
||||
image_info_t *image_info,
|
||||
pdf_page_handle page)
|
||||
pdf_page_handle page,
|
||||
position_t position)
|
||||
{
|
||||
bool result = 0;
|
||||
Rect rect;
|
||||
@@ -328,12 +347,12 @@ static bool process_tiff_image (int image, /* range 1 .. n */
|
||||
pdf_write_text (page);
|
||||
#else
|
||||
pdf_write_g4_fax_image (page,
|
||||
0, 0, /* x, y */
|
||||
position.x, position.y,
|
||||
image_info->width_points, image_info->height_points,
|
||||
image_info->negative,
|
||||
bitmap,
|
||||
0, /* ImageMask */
|
||||
0, 0, 0, /* r, g, b */
|
||||
0); /* BlackIs1 */
|
||||
input_attributes.colormap,
|
||||
input_attributes.transparency);
|
||||
#endif
|
||||
|
||||
result = 1;
|
||||
|
||||
Reference in New Issue
Block a user