Built SDL2_image and _mixer static

This commit is contained in:
2022-09-30 15:49:16 -04:00
parent e2605bf6c1
commit 1dec4347e0
4473 changed files with 1964551 additions and 9 deletions

View File

@ -0,0 +1,125 @@
# CMake build for libtiff
#
# Copyright © 2015 Open Microscopy Environment / University of Dundee
# Written by Roger Leigh <rleigh@codelibre.net>
#
# Permission to use, copy, modify, distribute, and sell this software and
# its documentation for any purpose is hereby granted without fee, provided
# that (i) the above copyright notices and this permission notice appear in
# all copies of the software and related documentation, and (ii) the names of
# Sam Leffler and Silicon Graphics may not be used in any advertising or
# publicity relating to the software without the specific, prior written
# permission of Sam Leffler and Silicon Graphics.
#
# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
#
# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
extra_dist(Makefile.vc)
include_directories(${PROJECT_SOURCE_DIR}/libtiff
${PROJECT_BINARY_DIR}/libtiff
${PROJECT_SOURCE_DIR}/port
${CMAKE_CURRENT_BINARY_DIR})
add_executable(fax2ps fax2ps.c)
target_link_libraries(fax2ps tiff port)
add_executable(fax2tiff fax2tiff.c)
target_link_libraries(fax2tiff tiff port)
add_executable(pal2rgb pal2rgb.c)
target_link_libraries(pal2rgb tiff port)
add_executable(ppm2tiff ppm2tiff.c)
target_link_libraries(ppm2tiff tiff port)
add_executable(raw2tiff raw2tiff.c)
target_link_libraries(raw2tiff tiff port)
add_executable(rgb2ycbcr rgb2ycbcr.c)
target_link_libraries(rgb2ycbcr tiff port)
add_executable(thumbnail thumbnail.c)
target_link_libraries(thumbnail tiff port)
add_executable(tiff2bw tiff2bw.c)
target_link_libraries(tiff2bw tiff port)
add_executable(tiff2pdf tiff2pdf.c)
target_link_libraries(tiff2pdf tiff port)
add_executable(tiff2ps tiff2ps.c)
target_link_libraries(tiff2ps tiff port)
add_executable(tiff2rgba tiff2rgba.c)
target_link_libraries(tiff2rgba tiff port)
add_executable(tiffcmp tiffcmp.c)
target_link_libraries(tiffcmp tiff port)
add_executable(tiffcp tiffcp.c)
target_link_libraries(tiffcp tiff port)
add_executable(tiffcrop tiffcrop.c)
target_link_libraries(tiffcrop tiff port)
add_executable(tiffdither tiffdither.c)
target_link_libraries(tiffdither tiff port)
add_executable(tiffdump tiffdump.c)
target_link_libraries(tiffdump tiff port)
add_executable(tiffinfo tiffinfo.c)
target_link_libraries(tiffinfo tiff port)
add_executable(tiffmedian tiffmedian.c)
target_link_libraries(tiffmedian tiff port)
add_executable(tiffset tiffset.c)
target_link_libraries(tiffset tiff port)
add_executable(tiffsplit tiffsplit.c)
target_link_libraries(tiffsplit tiff port)
install(TARGETS fax2ps
fax2tiff
pal2rgb
ppm2tiff
raw2tiff
tiff2bw
tiff2pdf
tiff2ps
tiff2rgba
tiffcmp
tiffcp
tiffcrop
tiffdither
tiffdump
tiffinfo
tiffmedian
tiffset
tiffsplit
RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
if(HAVE_OPENGL)
if(OPENGL_INCLUDE_DIR)
include_directories(${OPENGL_INCLUDE_DIR})
endif()
if(GLUT_INCLUDE_DIR)
include_directories(${GLUT_INCLUDE_DIR})
endif()
add_executable(tiffgt tiffgt.c)
target_link_libraries(tiffgt tiff ${GLUT_LIBRARIES} ${OPENGL_LIBRARIES})
install(TARGETS tiffgt
RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
endif()

View File

@ -0,0 +1,138 @@
# Tag Image File Format (TIFF) Software
#
# Copyright (C) 2004, Andrey Kiselev <dron@ak4719.spb.edu>
#
# Permission to use, copy, modify, distribute, and sell this software and
# its documentation for any purpose is hereby granted without fee, provided
# that (i) the above copyright notices and this permission notice appear in
# all copies of the software and related documentation, and (ii) the names of
# Sam Leffler and Silicon Graphics may not be used in any advertising or
# publicity relating to the software without the specific, prior written
# permission of Sam Leffler and Silicon Graphics.
#
# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
#
# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# Process this file with automake to produce Makefile.in.
LIBPORT = $(top_builddir)/port/libport.la
LIBTIFF = $(top_builddir)/libtiff/libtiff.la
EXTRA_DIST = \
CMakeLists.txt \
Makefile.vc
bin_PROGRAMS = \
fax2ps \
fax2tiff \
pal2rgb \
ppm2tiff \
raw2tiff \
tiff2bw \
tiff2pdf \
tiff2ps \
tiff2rgba \
tiffcmp \
tiffcp \
tiffcrop \
tiffdither \
tiffdump \
tiffinfo \
tiffmedian \
tiffset \
tiffsplit
if HAVE_OPENGL
bin_PROGRAMS += tiffgt
endif
EXTRA_PROGRAMS = rgb2ycbcr thumbnail
# Executable programs which need to be built in order to support tests
check_PROGRAMS = \
rgb2ycbcr \
thumbnail
if HAVE_RPATH
AM_LDFLAGS = $(LIBDIR)
endif
fax2ps_SOURCES = fax2ps.c
fax2ps_LDADD = $(LIBTIFF) $(LIBPORT)
fax2tiff_SOURCES = fax2tiff.c
fax2tiff_LDADD = $(LIBTIFF) $(LIBPORT)
pal2rgb_SOURCES = pal2rgb.c
pal2rgb_LDADD = $(LIBTIFF) $(LIBPORT)
ppm2tiff_SOURCES = ppm2tiff.c
ppm2tiff_LDADD = $(LIBTIFF) $(LIBPORT)
raw2tiff_SOURCES = raw2tiff.c
raw2tiff_LDADD = $(LIBTIFF) $(LIBPORT)
rgb2ycbcr_SOURCES = rgb2ycbcr.c
rgb2ycbcr_LDADD = $(LIBTIFF) $(LIBPORT)
thumbnail_SOURCES = thumbnail.c
thumbnail_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2bw_SOURCES = tiff2bw.c
tiff2bw_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2pdf_SOURCES = tiff2pdf.c
tiff2pdf_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2ps_SOURCES = tiff2ps.c
tiff2ps_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2rgba_SOURCES = tiff2rgba.c
tiff2rgba_LDADD = $(LIBTIFF) $(LIBPORT)
tiffcmp_SOURCES = tiffcmp.c
tiffcmp_LDADD = $(LIBTIFF) $(LIBPORT)
tiffcp_SOURCES = tiffcp.c
tiffcp_LDADD = $(LIBTIFF) $(LIBPORT)
tiffcrop_SOURCES = tiffcrop.c
tiffcrop_LDADD = $(LIBTIFF) $(LIBPORT)
tiffdither_SOURCES = tiffdither.c
tiffdither_LDADD = $(LIBTIFF) $(LIBPORT)
tiffdump_SOURCES = tiffdump.c
tiffdump_LDADD = $(LIBTIFF) $(LIBPORT)
tiffinfo_SOURCES = tiffinfo.c
tiffinfo_LDADD = $(LIBTIFF) $(LIBPORT)
tiffmedian_SOURCES = tiffmedian.c
tiffmedian_LDADD = $(LIBTIFF) $(LIBPORT)
tiffset_SOURCES = tiffset.c
tiffset_LDADD = $(LIBTIFF) $(LIBPORT)
tiffsplit_SOURCES = tiffsplit.c
tiffsplit_LDADD = $(LIBTIFF) $(LIBPORT)
tiffgt_SOURCES = tiffgt.c
tiffgt_CFLAGS = $(CFLAGS) $(GLUT_CFLAGS) $(AM_CFLAGS)
tiffgt_LDADD = $(LIBTIFF) $(LIBPORT) $(X_LIBS) $(GLUT_LIBS)
AM_CPPFLAGS = -I$(top_srcdir)/libtiff
echo:
(echo $(CFLAGS))
(echo $(tiffgt_CFLAGS))
(echo $(GL_CFLAGS))
(echo $(GLU_CFLAGS))
(echo $(GLUT_CFLAGS))

View File

@ -0,0 +1,955 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Tag Image File Format (TIFF) Software
#
# Copyright (C) 2004, Andrey Kiselev <dron@ak4719.spb.edu>
#
# Permission to use, copy, modify, distribute, and sell this software and
# its documentation for any purpose is hereby granted without fee, provided
# that (i) the above copyright notices and this permission notice appear in
# all copies of the software and related documentation, and (ii) the names of
# Sam Leffler and Silicon Graphics may not be used in any advertising or
# publicity relating to the software without the specific, prior written
# permission of Sam Leffler and Silicon Graphics.
#
# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
#
# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# Process this file with automake to produce Makefile.in.
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = fax2ps$(EXEEXT) fax2tiff$(EXEEXT) pal2rgb$(EXEEXT) \
ppm2tiff$(EXEEXT) raw2tiff$(EXEEXT) tiff2bw$(EXEEXT) \
tiff2pdf$(EXEEXT) tiff2ps$(EXEEXT) tiff2rgba$(EXEEXT) \
tiffcmp$(EXEEXT) tiffcp$(EXEEXT) tiffcrop$(EXEEXT) \
tiffdither$(EXEEXT) tiffdump$(EXEEXT) tiffinfo$(EXEEXT) \
tiffmedian$(EXEEXT) tiffset$(EXEEXT) tiffsplit$(EXEEXT) \
$(am__EXEEXT_1)
@HAVE_OPENGL_TRUE@am__append_1 = tiffgt
EXTRA_PROGRAMS = rgb2ycbcr$(EXEEXT) thumbnail$(EXEEXT)
check_PROGRAMS = rgb2ycbcr$(EXEEXT) thumbnail$(EXEEXT)
subdir = tools
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/libtiff/tif_config.h \
$(top_builddir)/libtiff/tiffconf.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
@HAVE_OPENGL_TRUE@am__EXEEXT_1 = tiffgt$(EXEEXT)
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_fax2ps_OBJECTS = fax2ps.$(OBJEXT)
fax2ps_OBJECTS = $(am_fax2ps_OBJECTS)
fax2ps_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
am_fax2tiff_OBJECTS = fax2tiff.$(OBJEXT)
fax2tiff_OBJECTS = $(am_fax2tiff_OBJECTS)
fax2tiff_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_pal2rgb_OBJECTS = pal2rgb.$(OBJEXT)
pal2rgb_OBJECTS = $(am_pal2rgb_OBJECTS)
pal2rgb_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_ppm2tiff_OBJECTS = ppm2tiff.$(OBJEXT)
ppm2tiff_OBJECTS = $(am_ppm2tiff_OBJECTS)
ppm2tiff_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_raw2tiff_OBJECTS = raw2tiff.$(OBJEXT)
raw2tiff_OBJECTS = $(am_raw2tiff_OBJECTS)
raw2tiff_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_rgb2ycbcr_OBJECTS = rgb2ycbcr.$(OBJEXT)
rgb2ycbcr_OBJECTS = $(am_rgb2ycbcr_OBJECTS)
rgb2ycbcr_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_thumbnail_OBJECTS = thumbnail.$(OBJEXT)
thumbnail_OBJECTS = $(am_thumbnail_OBJECTS)
thumbnail_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiff2bw_OBJECTS = tiff2bw.$(OBJEXT)
tiff2bw_OBJECTS = $(am_tiff2bw_OBJECTS)
tiff2bw_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiff2pdf_OBJECTS = tiff2pdf.$(OBJEXT)
tiff2pdf_OBJECTS = $(am_tiff2pdf_OBJECTS)
tiff2pdf_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiff2ps_OBJECTS = tiff2ps.$(OBJEXT)
tiff2ps_OBJECTS = $(am_tiff2ps_OBJECTS)
tiff2ps_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiff2rgba_OBJECTS = tiff2rgba.$(OBJEXT)
tiff2rgba_OBJECTS = $(am_tiff2rgba_OBJECTS)
tiff2rgba_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffcmp_OBJECTS = tiffcmp.$(OBJEXT)
tiffcmp_OBJECTS = $(am_tiffcmp_OBJECTS)
tiffcmp_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffcp_OBJECTS = tiffcp.$(OBJEXT)
tiffcp_OBJECTS = $(am_tiffcp_OBJECTS)
tiffcp_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffcrop_OBJECTS = tiffcrop.$(OBJEXT)
tiffcrop_OBJECTS = $(am_tiffcrop_OBJECTS)
tiffcrop_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffdither_OBJECTS = tiffdither.$(OBJEXT)
tiffdither_OBJECTS = $(am_tiffdither_OBJECTS)
tiffdither_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffdump_OBJECTS = tiffdump.$(OBJEXT)
tiffdump_OBJECTS = $(am_tiffdump_OBJECTS)
tiffdump_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffgt_OBJECTS = tiffgt-tiffgt.$(OBJEXT)
tiffgt_OBJECTS = $(am_tiffgt_OBJECTS)
am__DEPENDENCIES_1 =
tiffgt_DEPENDENCIES = $(LIBTIFF) $(LIBPORT) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
tiffgt_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(tiffgt_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
am_tiffinfo_OBJECTS = tiffinfo.$(OBJEXT)
tiffinfo_OBJECTS = $(am_tiffinfo_OBJECTS)
tiffinfo_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffmedian_OBJECTS = tiffmedian.$(OBJEXT)
tiffmedian_OBJECTS = $(am_tiffmedian_OBJECTS)
tiffmedian_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffset_OBJECTS = tiffset.$(OBJEXT)
tiffset_OBJECTS = $(am_tiffset_OBJECTS)
tiffset_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
am_tiffsplit_OBJECTS = tiffsplit.$(OBJEXT)
tiffsplit_OBJECTS = $(am_tiffsplit_OBJECTS)
tiffsplit_DEPENDENCIES = $(LIBTIFF) $(LIBPORT)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/libtiff
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(fax2ps_SOURCES) $(fax2tiff_SOURCES) $(pal2rgb_SOURCES) \
$(ppm2tiff_SOURCES) $(raw2tiff_SOURCES) $(rgb2ycbcr_SOURCES) \
$(thumbnail_SOURCES) $(tiff2bw_SOURCES) $(tiff2pdf_SOURCES) \
$(tiff2ps_SOURCES) $(tiff2rgba_SOURCES) $(tiffcmp_SOURCES) \
$(tiffcp_SOURCES) $(tiffcrop_SOURCES) $(tiffdither_SOURCES) \
$(tiffdump_SOURCES) $(tiffgt_SOURCES) $(tiffinfo_SOURCES) \
$(tiffmedian_SOURCES) $(tiffset_SOURCES) $(tiffsplit_SOURCES)
DIST_SOURCES = $(fax2ps_SOURCES) $(fax2tiff_SOURCES) \
$(pal2rgb_SOURCES) $(ppm2tiff_SOURCES) $(raw2tiff_SOURCES) \
$(rgb2ycbcr_SOURCES) $(thumbnail_SOURCES) $(tiff2bw_SOURCES) \
$(tiff2pdf_SOURCES) $(tiff2ps_SOURCES) $(tiff2rgba_SOURCES) \
$(tiffcmp_SOURCES) $(tiffcp_SOURCES) $(tiffcrop_SOURCES) \
$(tiffdither_SOURCES) $(tiffdump_SOURCES) $(tiffgt_SOURCES) \
$(tiffinfo_SOURCES) $(tiffmedian_SOURCES) $(tiffset_SOURCES) \
$(tiffsplit_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \
$(top_srcdir)/config/mkinstalldirs
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMAKE = @CMAKE@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GLUT_CFLAGS = @GLUT_CFLAGS@
GLUT_LIBS = @GLUT_LIBS@
GLU_CFLAGS = @GLU_CFLAGS@
GLU_LIBS = @GLU_LIBS@
GL_CFLAGS = @GL_CFLAGS@
GL_LIBS = @GL_LIBS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBDIR = @LIBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTIFF_ALPHA_VERSION = @LIBTIFF_ALPHA_VERSION@
LIBTIFF_DOCDIR = @LIBTIFF_DOCDIR@
LIBTIFF_MAJOR_VERSION = @LIBTIFF_MAJOR_VERSION@
LIBTIFF_MICRO_VERSION = @LIBTIFF_MICRO_VERSION@
LIBTIFF_MINOR_VERSION = @LIBTIFF_MINOR_VERSION@
LIBTIFF_RELEASE_DATE = @LIBTIFF_RELEASE_DATE@
LIBTIFF_VERSION = @LIBTIFF_VERSION@
LIBTIFF_VERSION_INFO = @LIBTIFF_VERSION_INFO@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
XMKMF = @XMKMF@
X_CFLAGS = @X_CFLAGS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
tiff_libs_private = @tiff_libs_private@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
LIBPORT = $(top_builddir)/port/libport.la
LIBTIFF = $(top_builddir)/libtiff/libtiff.la
EXTRA_DIST = \
CMakeLists.txt \
Makefile.vc
@HAVE_RPATH_TRUE@AM_LDFLAGS = $(LIBDIR)
fax2ps_SOURCES = fax2ps.c
fax2ps_LDADD = $(LIBTIFF) $(LIBPORT)
fax2tiff_SOURCES = fax2tiff.c
fax2tiff_LDADD = $(LIBTIFF) $(LIBPORT)
pal2rgb_SOURCES = pal2rgb.c
pal2rgb_LDADD = $(LIBTIFF) $(LIBPORT)
ppm2tiff_SOURCES = ppm2tiff.c
ppm2tiff_LDADD = $(LIBTIFF) $(LIBPORT)
raw2tiff_SOURCES = raw2tiff.c
raw2tiff_LDADD = $(LIBTIFF) $(LIBPORT)
rgb2ycbcr_SOURCES = rgb2ycbcr.c
rgb2ycbcr_LDADD = $(LIBTIFF) $(LIBPORT)
thumbnail_SOURCES = thumbnail.c
thumbnail_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2bw_SOURCES = tiff2bw.c
tiff2bw_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2pdf_SOURCES = tiff2pdf.c
tiff2pdf_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2ps_SOURCES = tiff2ps.c
tiff2ps_LDADD = $(LIBTIFF) $(LIBPORT)
tiff2rgba_SOURCES = tiff2rgba.c
tiff2rgba_LDADD = $(LIBTIFF) $(LIBPORT)
tiffcmp_SOURCES = tiffcmp.c
tiffcmp_LDADD = $(LIBTIFF) $(LIBPORT)
tiffcp_SOURCES = tiffcp.c
tiffcp_LDADD = $(LIBTIFF) $(LIBPORT)
tiffcrop_SOURCES = tiffcrop.c
tiffcrop_LDADD = $(LIBTIFF) $(LIBPORT)
tiffdither_SOURCES = tiffdither.c
tiffdither_LDADD = $(LIBTIFF) $(LIBPORT)
tiffdump_SOURCES = tiffdump.c
tiffdump_LDADD = $(LIBTIFF) $(LIBPORT)
tiffinfo_SOURCES = tiffinfo.c
tiffinfo_LDADD = $(LIBTIFF) $(LIBPORT)
tiffmedian_SOURCES = tiffmedian.c
tiffmedian_LDADD = $(LIBTIFF) $(LIBPORT)
tiffset_SOURCES = tiffset.c
tiffset_LDADD = $(LIBTIFF) $(LIBPORT)
tiffsplit_SOURCES = tiffsplit.c
tiffsplit_LDADD = $(LIBTIFF) $(LIBPORT)
tiffgt_SOURCES = tiffgt.c
tiffgt_CFLAGS = $(CFLAGS) $(GLUT_CFLAGS) $(AM_CFLAGS)
tiffgt_LDADD = $(LIBTIFF) $(LIBPORT) $(X_LIBS) $(GLUT_LIBS)
AM_CPPFLAGS = -I$(top_srcdir)/libtiff
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign tools/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
|| test -f $$p1 \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
fax2ps$(EXEEXT): $(fax2ps_OBJECTS) $(fax2ps_DEPENDENCIES) $(EXTRA_fax2ps_DEPENDENCIES)
@rm -f fax2ps$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fax2ps_OBJECTS) $(fax2ps_LDADD) $(LIBS)
fax2tiff$(EXEEXT): $(fax2tiff_OBJECTS) $(fax2tiff_DEPENDENCIES) $(EXTRA_fax2tiff_DEPENDENCIES)
@rm -f fax2tiff$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fax2tiff_OBJECTS) $(fax2tiff_LDADD) $(LIBS)
pal2rgb$(EXEEXT): $(pal2rgb_OBJECTS) $(pal2rgb_DEPENDENCIES) $(EXTRA_pal2rgb_DEPENDENCIES)
@rm -f pal2rgb$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(pal2rgb_OBJECTS) $(pal2rgb_LDADD) $(LIBS)
ppm2tiff$(EXEEXT): $(ppm2tiff_OBJECTS) $(ppm2tiff_DEPENDENCIES) $(EXTRA_ppm2tiff_DEPENDENCIES)
@rm -f ppm2tiff$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(ppm2tiff_OBJECTS) $(ppm2tiff_LDADD) $(LIBS)
raw2tiff$(EXEEXT): $(raw2tiff_OBJECTS) $(raw2tiff_DEPENDENCIES) $(EXTRA_raw2tiff_DEPENDENCIES)
@rm -f raw2tiff$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(raw2tiff_OBJECTS) $(raw2tiff_LDADD) $(LIBS)
rgb2ycbcr$(EXEEXT): $(rgb2ycbcr_OBJECTS) $(rgb2ycbcr_DEPENDENCIES) $(EXTRA_rgb2ycbcr_DEPENDENCIES)
@rm -f rgb2ycbcr$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(rgb2ycbcr_OBJECTS) $(rgb2ycbcr_LDADD) $(LIBS)
thumbnail$(EXEEXT): $(thumbnail_OBJECTS) $(thumbnail_DEPENDENCIES) $(EXTRA_thumbnail_DEPENDENCIES)
@rm -f thumbnail$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(thumbnail_OBJECTS) $(thumbnail_LDADD) $(LIBS)
tiff2bw$(EXEEXT): $(tiff2bw_OBJECTS) $(tiff2bw_DEPENDENCIES) $(EXTRA_tiff2bw_DEPENDENCIES)
@rm -f tiff2bw$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiff2bw_OBJECTS) $(tiff2bw_LDADD) $(LIBS)
tiff2pdf$(EXEEXT): $(tiff2pdf_OBJECTS) $(tiff2pdf_DEPENDENCIES) $(EXTRA_tiff2pdf_DEPENDENCIES)
@rm -f tiff2pdf$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiff2pdf_OBJECTS) $(tiff2pdf_LDADD) $(LIBS)
tiff2ps$(EXEEXT): $(tiff2ps_OBJECTS) $(tiff2ps_DEPENDENCIES) $(EXTRA_tiff2ps_DEPENDENCIES)
@rm -f tiff2ps$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiff2ps_OBJECTS) $(tiff2ps_LDADD) $(LIBS)
tiff2rgba$(EXEEXT): $(tiff2rgba_OBJECTS) $(tiff2rgba_DEPENDENCIES) $(EXTRA_tiff2rgba_DEPENDENCIES)
@rm -f tiff2rgba$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiff2rgba_OBJECTS) $(tiff2rgba_LDADD) $(LIBS)
tiffcmp$(EXEEXT): $(tiffcmp_OBJECTS) $(tiffcmp_DEPENDENCIES) $(EXTRA_tiffcmp_DEPENDENCIES)
@rm -f tiffcmp$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffcmp_OBJECTS) $(tiffcmp_LDADD) $(LIBS)
tiffcp$(EXEEXT): $(tiffcp_OBJECTS) $(tiffcp_DEPENDENCIES) $(EXTRA_tiffcp_DEPENDENCIES)
@rm -f tiffcp$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffcp_OBJECTS) $(tiffcp_LDADD) $(LIBS)
tiffcrop$(EXEEXT): $(tiffcrop_OBJECTS) $(tiffcrop_DEPENDENCIES) $(EXTRA_tiffcrop_DEPENDENCIES)
@rm -f tiffcrop$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffcrop_OBJECTS) $(tiffcrop_LDADD) $(LIBS)
tiffdither$(EXEEXT): $(tiffdither_OBJECTS) $(tiffdither_DEPENDENCIES) $(EXTRA_tiffdither_DEPENDENCIES)
@rm -f tiffdither$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffdither_OBJECTS) $(tiffdither_LDADD) $(LIBS)
tiffdump$(EXEEXT): $(tiffdump_OBJECTS) $(tiffdump_DEPENDENCIES) $(EXTRA_tiffdump_DEPENDENCIES)
@rm -f tiffdump$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffdump_OBJECTS) $(tiffdump_LDADD) $(LIBS)
tiffgt$(EXEEXT): $(tiffgt_OBJECTS) $(tiffgt_DEPENDENCIES) $(EXTRA_tiffgt_DEPENDENCIES)
@rm -f tiffgt$(EXEEXT)
$(AM_V_CCLD)$(tiffgt_LINK) $(tiffgt_OBJECTS) $(tiffgt_LDADD) $(LIBS)
tiffinfo$(EXEEXT): $(tiffinfo_OBJECTS) $(tiffinfo_DEPENDENCIES) $(EXTRA_tiffinfo_DEPENDENCIES)
@rm -f tiffinfo$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffinfo_OBJECTS) $(tiffinfo_LDADD) $(LIBS)
tiffmedian$(EXEEXT): $(tiffmedian_OBJECTS) $(tiffmedian_DEPENDENCIES) $(EXTRA_tiffmedian_DEPENDENCIES)
@rm -f tiffmedian$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffmedian_OBJECTS) $(tiffmedian_LDADD) $(LIBS)
tiffset$(EXEEXT): $(tiffset_OBJECTS) $(tiffset_DEPENDENCIES) $(EXTRA_tiffset_DEPENDENCIES)
@rm -f tiffset$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffset_OBJECTS) $(tiffset_LDADD) $(LIBS)
tiffsplit$(EXEEXT): $(tiffsplit_OBJECTS) $(tiffsplit_DEPENDENCIES) $(EXTRA_tiffsplit_DEPENDENCIES)
@rm -f tiffsplit$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tiffsplit_OBJECTS) $(tiffsplit_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fax2ps.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fax2tiff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pal2rgb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppm2tiff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw2tiff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rgb2ycbcr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thumbnail.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiff2bw.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiff2pdf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiff2ps.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiff2rgba.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffcmp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffcp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffcrop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffdither.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffdump.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffgt-tiffgt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffinfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffmedian.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffset.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiffsplit.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
tiffgt-tiffgt.o: tiffgt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tiffgt_CFLAGS) $(CFLAGS) -MT tiffgt-tiffgt.o -MD -MP -MF $(DEPDIR)/tiffgt-tiffgt.Tpo -c -o tiffgt-tiffgt.o `test -f 'tiffgt.c' || echo '$(srcdir)/'`tiffgt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tiffgt-tiffgt.Tpo $(DEPDIR)/tiffgt-tiffgt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tiffgt.c' object='tiffgt-tiffgt.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tiffgt_CFLAGS) $(CFLAGS) -c -o tiffgt-tiffgt.o `test -f 'tiffgt.c' || echo '$(srcdir)/'`tiffgt.c
tiffgt-tiffgt.obj: tiffgt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tiffgt_CFLAGS) $(CFLAGS) -MT tiffgt-tiffgt.obj -MD -MP -MF $(DEPDIR)/tiffgt-tiffgt.Tpo -c -o tiffgt-tiffgt.obj `if test -f 'tiffgt.c'; then $(CYGPATH_W) 'tiffgt.c'; else $(CYGPATH_W) '$(srcdir)/tiffgt.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tiffgt-tiffgt.Tpo $(DEPDIR)/tiffgt-tiffgt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tiffgt.c' object='tiffgt-tiffgt.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tiffgt_CFLAGS) $(CFLAGS) -c -o tiffgt-tiffgt.obj `if test -f 'tiffgt.c'; then $(CYGPATH_W) 'tiffgt.c'; else $(CYGPATH_W) '$(srcdir)/tiffgt.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
clean-libtool mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binPROGRAMS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS
.MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-binPROGRAMS install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
.PRECIOUS: Makefile
echo:
(echo $(CFLAGS))
(echo $(tiffgt_CFLAGS))
(echo $(GL_CFLAGS))
(echo $(GLU_CFLAGS))
(echo $(GLUT_CFLAGS))
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,52 @@
# $Id: Makefile.vc,v 1.16 2016-06-05 19:54:03 bfriesen Exp $
#
# Copyright (C) 2004, Andrey Kiselev <dron@ak4719.spb.edu>
#
# Permission to use, copy, modify, distribute, and sell this software and
# its documentation for any purpose is hereby granted without fee, provided
# that (i) the above copyright notices and this permission notice appear in
# all copies of the software and related documentation, and (ii) the names of
# Sam Leffler and Silicon Graphics may not be used in any advertising or
# publicity relating to the software without the specific, prior written
# permission of Sam Leffler and Silicon Graphics.
#
# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
#
# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
# Makefile for MS Visual C and Watcom C compilers.
#
# To build:
# C:\libtiff\tools> nmake /f makefile.vc
!INCLUDE ..\nmake.opt
TARGETS = tiffinfo.exe tiffdump.exe fax2tiff.exe \
fax2ps.exe pal2rgb.exe ppm2tiff.exe \
rgb2ycbcr.exe thumbnail.exe raw2tiff.exe \
tiff2bw.exe tiff2rgba.exe tiff2pdf.exe tiff2ps.exe \
tiffcmp.exe tiffcp.exe tiffcrop.exe tiffdither.exe \
tiffmedian.exe tiffset.exe tiffsplit.exe
INCL = -I..\libtiff -I..\port -DNEED_LIBPORT
LIBS = $(LIBS) ..\port\libport.lib ..\libtiff\libtiff.lib
default: $(TARGETS)
.c.exe:
$(CC) $(CFLAGS) $*.c $(EXTRA_OBJ) $(LIBS)
tiffgt.exe:
$(CC) $(CFLAGS) tiffgt.c $(EXTRA_OBJ) $(LIBS)
clean:
-del *.exe
-del *.exe.manifest
-del *.obj

View File

@ -0,0 +1,463 @@
/* $Id: fax2ps.c,v 1.31 2015-09-06 18:24:27 bfriesen Exp $" */
/*
* Copyright (c) 1991-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffiop.h"
#include "tiffio.h"
float defxres = 204.; /* default x resolution (pixels/inch) */
float defyres = 98.; /* default y resolution (lines/inch) */
const float half = 0.5;
const float points = 72.0;
float pageWidth = 0; /* image page width (inches) */
float pageHeight = 0; /* image page length (inches) */
int scaleToPage = 0; /* if true, scale raster to page dimensions */
int totalPages = 0; /* total # pages printed */
int row; /* current output row */
int maxline = 512; /* max output line of PostScript */
/*
* Turn a bit-mapped scanline into the appropriate sequence
* of PostScript characters to be rendered.
*
* Original version written by Bret D. Whissel,
* Florida State University Meteorology Department
* March 13-15, 1995.
*/
static void
printruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
{
static struct {
char white, black;
unsigned short width;
} WBarr[] = {
{ 'd', 'n', 512 }, { 'e', 'o', 256 }, { 'f', 'p', 128 },
{ 'g', 'q', 64 }, { 'h', 'r', 32 }, { 'i', 's', 16 },
{ 'j', 't', 8 }, { 'k', 'u', 4 }, { 'l', 'v', 2 },
{ 'm', 'w', 1 }
};
static char* svalue =
" !\"#$&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abc";
int colormode = 1; /* 0 for white, 1 for black */
uint32 runlength = 0;
int n = maxline;
uint32 x = 0;
int l;
(void) buf;
printf("%d m(", row++);
while (runs < erun) {
if (runlength <= 0) {
colormode ^= 1;
runlength = *runs++;
if (x+runlength > lastx)
runlength = runs[-1] = lastx-x;
x += runlength;
if (!colormode && runs == erun)
break; /* don't bother printing the final white run */
}
/*
* If a runlength is greater than 6 pixels, then spit out
* black or white characters until the runlength drops to
* 6 or less. Once a runlength is <= 6, then combine black
* and white runlengths until a 6-pixel pattern is obtained.
* Then write out the special character. Six-pixel patterns
* were selected since 64 patterns is the largest power of
* two less than the 92 "easily printable" PostScript
* characters (i.e., no escape codes or octal chars).
*/
l = 0;
while (runlength > 6) { /* Run is greater than six... */
if (runlength >= WBarr[l].width) {
if (n == 0) {
putchar('\n');
n = maxline;
}
putchar(colormode ? WBarr[l].black : WBarr[l].white), n--;
runlength -= WBarr[l].width;
} else
l++;
}
while (runlength > 0 && runlength <= 6) {
uint32 bitsleft = 6;
int t = 0;
while (bitsleft) {
if (runlength <= bitsleft) {
if (colormode)
t |= ((1 << runlength)-1) << (bitsleft-runlength);
bitsleft -= runlength;
runlength = 0;
if (bitsleft) {
if (runs >= erun)
break;
colormode ^= 1;
runlength = *runs++;
if (x+runlength > lastx)
runlength = runs[-1] = lastx-x;
x += runlength;
}
} else { /* runlength exceeds bits left */
if (colormode)
t |= ((1 << bitsleft)-1);
runlength -= bitsleft;
bitsleft = 0;
}
}
if (n == 0) {
putchar('\n');
n = maxline;
}
putchar(svalue[t]), n--;
}
}
printf(")s\n");
}
/*
* Create a special PostScript font for printing FAX documents. By taking
* advantage of the font-cacheing mechanism, a substantial speed-up in
* rendering time is realized.
*/
static void
emitFont(FILE* fd)
{
static const char* fontPrologue[] = {
"/newfont 10 dict def newfont begin /FontType 3 def /FontMatrix [1",
"0 0 1 0 0] def /FontBBox [0 0 512 1] def /Encoding 256 array def",
"0 1 31{Encoding exch /255 put}for 120 1 255{Encoding exch /255",
"put}for Encoding 37 /255 put Encoding 40 /255 put Encoding 41 /255",
"put Encoding 92 /255 put /count 0 def /ls{Encoding exch count 3",
"string cvs cvn put /count count 1 add def}def 32 1 36{ls}for",
"38 1 39{ls}for 42 1 91{ls}for 93 1 99{ls}for /count 100",
"def 100 1 119{ls}for /CharDict 5 dict def CharDict begin /white",
"{dup 255 eq{pop}{1 dict begin 100 sub neg 512 exch bitshift",
"/cw exch def cw 0 0 0 cw 1 setcachedevice end}ifelse}def /black",
"{dup 255 eq{pop}{1 dict begin 110 sub neg 512 exch bitshift",
"/cw exch def cw 0 0 0 cw 1 setcachedevice 0 0 moveto cw 0 rlineto",
"0 1 rlineto cw neg 0 rlineto closepath fill end}ifelse}def /numbuild",
"{dup 255 eq{pop}{6 0 0 0 6 1 setcachedevice 0 1 5{0 moveto",
"dup 32 and 32 eq{1 0 rlineto 0 1 rlineto -1 0 rlineto closepath",
"fill newpath}if 1 bitshift}for pop}ifelse}def /.notdef {}",
"def /255 {}def end /BuildChar{exch begin dup 110 ge{Encoding",
"exch get 3 string cvs cvi CharDict /black get}{dup 100 ge {Encoding",
"exch get 3 string cvs cvi CharDict /white get}{Encoding exch get",
"3 string cvs cvi CharDict /numbuild get}ifelse}ifelse exec end",
"}def end /Bitfont newfont definefont 1 scalefont setfont",
NULL
};
int i;
for (i = 0; fontPrologue[i] != NULL; i++)
fprintf(fd, "%s\n", fontPrologue[i]);
}
void
printTIF(TIFF* tif, uint16 pageNumber)
{
uint32 w, h;
uint16 unit, compression;
float xres, yres, scale = 1.0;
tstrip_t s, ns;
time_t creation_time;
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
if (!TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression)
|| compression < COMPRESSION_CCITTRLE
|| compression > COMPRESSION_CCITT_T6)
return;
if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) || !xres) {
TIFFWarning(TIFFFileName(tif),
"No x-resolution, assuming %g dpi", defxres);
xres = defxres;
}
if (!TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) || !yres) {
TIFFWarning(TIFFFileName(tif),
"No y-resolution, assuming %g lpi", defyres);
yres = defyres; /* XXX */
}
if (TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &unit) &&
unit == RESUNIT_CENTIMETER) {
xres *= 2.54F;
yres *= 2.54F;
}
if (pageWidth == 0)
pageWidth = w / xres;
if (pageHeight == 0)
pageHeight = h / yres;
printf("%%!PS-Adobe-3.0\n");
printf("%%%%Creator: fax2ps\n");
#ifdef notdef
printf("%%%%Title: %s\n", file);
#endif
creation_time = time(0);
printf("%%%%CreationDate: %s", ctime(&creation_time));
printf("%%%%Origin: 0 0\n");
printf("%%%%BoundingBox: 0 0 %u %u\n",
(int)(pageWidth * points), (int)(pageHeight * points)); /* XXX */
printf("%%%%Pages: (atend)\n");
printf("%%%%EndComments\n");
printf("%%%%BeginProlog\n");
emitFont(stdout);
printf("/d{bind def}def\n"); /* bind and def proc */
printf("/m{0 exch moveto}d\n");
printf("/s{show}d\n");
printf("/p{showpage}d \n"); /* end page */
printf("%%%%EndProlog\n");
printf("%%%%Page: \"%u\" %u\n", pageNumber, pageNumber);
printf("/$pageTop save def gsave\n");
if (scaleToPage)
scale = pageHeight / (h/yres) < pageWidth / (w/xres) ?
pageHeight / (h/yres) : pageWidth / (w/xres);
printf("%g %g translate\n",
points * (pageWidth - scale*w/xres) * half,
points * (scale*h/yres + (pageHeight - scale*h/yres) * half));
printf("%g %g scale\n", points/xres*scale, -points/yres*scale);
printf("0 setgray\n");
TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, printruns);
ns = TIFFNumberOfStrips(tif);
row = 0;
for (s = 0; s < ns; s++)
(void) TIFFReadEncodedStrip(tif, s, (tdata_t) NULL, (tsize_t) -1);
printf("p\n");
printf("grestore $pageTop restore\n");
totalPages++;
}
#define GetPageNumber(tif) \
TIFFGetField(tif, TIFFTAG_PAGENUMBER, &pn, &ptotal)
int
findPage(TIFF* tif, uint16 pageNumber)
{
uint16 pn = (uint16) -1;
uint16 ptotal = (uint16) -1;
if (GetPageNumber(tif)) {
while (pn != (pageNumber-1) && TIFFReadDirectory(tif) && GetPageNumber(tif))
;
return (pn == (pageNumber-1));
} else
return (TIFFSetDirectory(tif, (tdir_t)(pageNumber-1)));
}
void
fax2ps(TIFF* tif, uint16 npages, uint16* pages, char* filename)
{
if (npages > 0) {
uint16 pn, ptotal;
int i;
if (!GetPageNumber(tif))
fprintf(stderr, "%s: No page numbers, counting directories.\n",
filename);
for (i = 0; i < npages; i++) {
if (findPage(tif, pages[i]))
printTIF(tif, pages[i]);
else
fprintf(stderr, "%s: No page number %d\n", filename, pages[i]);
}
} else {
uint16 pageNumber = 0;
do
printTIF(tif, pageNumber++);
while (TIFFReadDirectory(tif));
}
}
#undef GetPageNumber
static int
pcompar(const void* va, const void* vb)
{
const int* pa = (const int*) va;
const int* pb = (const int*) vb;
return (*pa - *pb);
}
static void usage(int code);
int
main(int argc, char** argv)
{
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
uint16 *pages = NULL, npages = 0, pageNumber;
int c, dowarnings = 0; /* if 1, enable library warnings */
TIFF* tif;
while ((c = getopt(argc, argv, "l:p:x:y:W:H:wS")) != -1)
switch (c) {
case 'H': /* page height */
pageHeight = (float)atof(optarg);
break;
case 'S': /* scale to page */
scaleToPage = 1;
break;
case 'W': /* page width */
pageWidth = (float)atof(optarg);
break;
case 'p': /* print specific page */
pageNumber = (uint16)atoi(optarg);
if (pages)
pages = (uint16*) realloc(pages, (npages+1)*sizeof(uint16));
else
pages = (uint16*) malloc(sizeof(uint16));
if( pages == NULL )
{
fprintf(stderr, "Out of memory\n");
exit(-1);
}
pages[npages++] = pageNumber;
break;
case 'w':
dowarnings = 1;
break;
case 'x':
defxres = (float)atof(optarg);
break;
case 'y':
defyres = (float)atof(optarg);
break;
case 'l':
maxline = atoi(optarg);
break;
case '?':
usage(-1);
}
if (npages > 0)
qsort(pages, npages, sizeof(uint16), pcompar);
if (!dowarnings)
TIFFSetWarningHandler(0);
if (optind < argc) {
do {
tif = TIFFOpen(argv[optind], "r");
if (tif) {
fax2ps(tif, npages, pages, argv[optind]);
TIFFClose(tif);
} else
fprintf(stderr, "%s: Can not open, or not a TIFF file.\n",
argv[optind]);
} while (++optind < argc);
} else {
int n;
FILE* fd;
char buf[16*1024];
fd = tmpfile();
if (fd == NULL) {
fprintf(stderr, "Could not obtain temporary file.\n");
exit(-2);
}
#if defined(HAVE_SETMODE) && defined(O_BINARY)
setmode(fileno(stdin), O_BINARY);
#endif
while ((n = read(fileno(stdin), buf, sizeof (buf))) > 0) {
if (write(fileno(fd), buf, n) != n) {
fclose(fd);
fprintf(stderr,
"Could not copy stdin to temporary file.\n");
exit(-2);
}
}
_TIFF_lseek_f(fileno(fd), 0, SEEK_SET);
#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
tif = TIFFFdOpen(_get_osfhandle(fileno(fd)), "temp", "r");
#else
tif = TIFFFdOpen(fileno(fd), "temp", "r");
#endif
if (tif) {
fax2ps(tif, npages, pages, "<stdin>");
TIFFClose(tif);
} else
fprintf(stderr, "Can not open, or not a TIFF file.\n");
fclose(fd);
}
printf("%%%%Trailer\n");
printf("%%%%Pages: %u\n", totalPages);
printf("%%%%EOF\n");
return (0);
}
char* stuff[] = {
"usage: fax2ps [options] [input.tif ...]",
"where options are:",
" -w suppress warning messages",
" -l chars set maximum output line length for generated PostScript",
" -p page# select page to print (can use multiple times)",
" -x xres set default horizontal resolution of input data (dpi)",
" -y yres set default vertical resolution of input data (lpi)",
" -S scale output to page size",
" -W width set output page width (inches), default is 8.5",
" -H height set output page height (inches), default is 11",
NULL
};
static void
usage(int code)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(code);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,491 @@
/* $Id: fax2tiff.c,v 1.28 2017-10-29 18:28:45 bfriesen Exp $ */
/*
* Copyright (c) 1990-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* Convert a CCITT Group 3 or 4 FAX file to TIFF Group 3 or 4 format.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h> /* should have atof & getopt */
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffiop.h"
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
#endif
#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
TIFF *faxTIFF;
char *rowbuf;
char *refbuf;
uint32 xsize = 1728;
int verbose;
int stretch;
uint16 badfaxrun;
uint32 badfaxlines;
int copyFaxFile(TIFF* tifin, TIFF* tifout);
static void usage(void);
/*
Struct to carry client data. Note that it does not appear that the client
data is actually used in this program.
*/
typedef struct _FAX_Client_Data
{
#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
intptr_t fh; /* Operating system file handle */
#else
int fd; /* Integer file descriptor */
#endif
} FAX_Client_Data;
int
main(int argc, char* argv[])
{
FILE *in;
TIFF *out = NULL;
FAX_Client_Data client_data;
TIFFErrorHandler whandler = NULL;
int compression_in = COMPRESSION_CCITTFAX3;
int compression_out = COMPRESSION_CCITTFAX3;
int fillorder_in = FILLORDER_LSB2MSB;
int fillorder_out = FILLORDER_LSB2MSB;
uint32 group3options_in = 0; /* 1d-encoded */
uint32 group3options_out = 0; /* 1d-encoded */
uint32 group4options_in = 0; /* compressed */
uint32 group4options_out = 0; /* compressed */
uint32 defrowsperstrip = (uint32) 0;
uint32 rowsperstrip;
int photometric_in = PHOTOMETRIC_MINISWHITE;
int photometric_out = PHOTOMETRIC_MINISWHITE;
int mode = FAXMODE_CLASSF;
int rows;
int c;
int pn, npages;
float resY = 196.0;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
while ((c = getopt(argc, argv, "R:X:o:r:1234ABLMPUW5678abcflmprsuvwz?")) != -1)
switch (c) {
/* input-related options */
case '3': /* input is g3-encoded */
compression_in = COMPRESSION_CCITTFAX3;
break;
case '4': /* input is g4-encoded */
compression_in = COMPRESSION_CCITTFAX4;
break;
case 'U': /* input is uncompressed (g3 and g4) */
group3options_in |= GROUP3OPT_UNCOMPRESSED;
group4options_in |= GROUP4OPT_UNCOMPRESSED;
break;
case '1': /* input is 1d-encoded (g3 only) */
group3options_in &= ~GROUP3OPT_2DENCODING;
break;
case '2': /* input is 2d-encoded (g3 only) */
group3options_in |= GROUP3OPT_2DENCODING;
break;
case 'P': /* input has not-aligned EOL (g3 only) */
group3options_in &= ~GROUP3OPT_FILLBITS;
break;
case 'A': /* input has aligned EOL (g3 only) */
group3options_in |= GROUP3OPT_FILLBITS;
break;
case 'W': /* input has 0 mean white */
photometric_in = PHOTOMETRIC_MINISWHITE;
break;
case 'B': /* input has 0 mean black */
photometric_in = PHOTOMETRIC_MINISBLACK;
break;
case 'L': /* input has lsb-to-msb fillorder */
fillorder_in = FILLORDER_LSB2MSB;
break;
case 'M': /* input has msb-to-lsb fillorder */
fillorder_in = FILLORDER_MSB2LSB;
break;
case 'R': /* input resolution */
resY = (float) atof(optarg);
break;
case 'X': /* input width */
xsize = (uint32) atoi(optarg);
break;
/* output-related options */
case '7': /* generate g3-encoded output */
compression_out = COMPRESSION_CCITTFAX3;
break;
case '8': /* generate g4-encoded output */
compression_out = COMPRESSION_CCITTFAX4;
break;
case 'u': /* generate uncompressed output (g3 and g4) */
group3options_out |= GROUP3OPT_UNCOMPRESSED;
group4options_out |= GROUP4OPT_UNCOMPRESSED;
break;
case '5': /* generate 1d-encoded output (g3 only) */
group3options_out &= ~GROUP3OPT_2DENCODING;
break;
case '6': /* generate 2d-encoded output (g3 only) */
group3options_out |= GROUP3OPT_2DENCODING;
break;
case 'c': /* generate "classic" g3 format */
mode = FAXMODE_CLASSIC;
break;
case 'f': /* generate Class F format */
mode = FAXMODE_CLASSF;
break;
case 'm': /* output's fillorder is msb-to-lsb */
fillorder_out = FILLORDER_MSB2LSB;
break;
case 'l': /* output's fillorder is lsb-to-msb */
fillorder_out = FILLORDER_LSB2MSB;
break;
case 'o':
out = TIFFOpen(optarg, "w");
if (out == NULL) {
fprintf(stderr,
"%s: Can not create or open %s\n",
argv[0], optarg);
return EXIT_FAILURE;
}
break;
case 'a': /* generate EOL-aligned output (g3 only) */
group3options_out |= GROUP3OPT_FILLBITS;
break;
case 'p': /* generate not EOL-aligned output (g3 only) */
group3options_out &= ~GROUP3OPT_FILLBITS;
break;
case 'r': /* rows/strip */
defrowsperstrip = atol(optarg);
break;
case 's': /* stretch image by dup'ng scanlines */
stretch = 1;
break;
case 'w': /* undocumented -- for testing */
photometric_out = PHOTOMETRIC_MINISWHITE;
break;
case 'b': /* undocumented -- for testing */
photometric_out = PHOTOMETRIC_MINISBLACK;
break;
case 'z': /* undocumented -- for testing */
compression_out = COMPRESSION_LZW;
break;
case 'v': /* -v for info */
verbose++;
break;
case '?':
usage();
/*NOTREACHED*/
}
npages = argc - optind;
if (npages < 1)
usage();
rowbuf = _TIFFmalloc(TIFFhowmany8(xsize));
refbuf = _TIFFmalloc(TIFFhowmany8(xsize));
if (rowbuf == NULL || refbuf == NULL) {
fprintf(stderr, "%s: Not enough memory\n", argv[0]);
return (EXIT_FAILURE);
}
if (out == NULL) {
out = TIFFOpen("fax.tif", "w");
if (out == NULL) {
fprintf(stderr, "%s: Can not create fax.tif\n",
argv[0]);
return (EXIT_FAILURE);
}
}
faxTIFF = TIFFClientOpen("(FakeInput)", "w",
/* TIFFClientOpen() fails if we don't set existing value here */
TIFFClientdata(out),
TIFFGetReadProc(out), TIFFGetWriteProc(out),
TIFFGetSeekProc(out), TIFFGetCloseProc(out),
TIFFGetSizeProc(out), TIFFGetMapFileProc(out),
TIFFGetUnmapFileProc(out));
if (faxTIFF == NULL) {
fprintf(stderr, "%s: Can not create fake input file\n",
argv[0]);
return (EXIT_FAILURE);
}
TIFFSetMode(faxTIFF, O_RDONLY);
TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH, xsize);
TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE, 1);
TIFFSetField(faxTIFF, TIFFTAG_FILLORDER, fillorder_in);
TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC, photometric_in);
TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION, resY);
TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
/* NB: this must be done after directory info is setup */
TIFFSetField(faxTIFF, TIFFTAG_COMPRESSION, compression_in);
if (compression_in == COMPRESSION_CCITTFAX3)
TIFFSetField(faxTIFF, TIFFTAG_GROUP3OPTIONS, group3options_in);
else if (compression_in == COMPRESSION_CCITTFAX4)
TIFFSetField(faxTIFF, TIFFTAG_GROUP4OPTIONS, group4options_in);
for (pn = 0; optind < argc; pn++, optind++) {
in = fopen(argv[optind], "rb");
if (in == NULL) {
fprintf(stderr,
"%s: %s: Can not open\n", argv[0], argv[optind]);
continue;
}
#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
client_data.fh = _get_osfhandle(fileno(in));
#else
client_data.fd = fileno(in);
#endif
TIFFSetClientdata(faxTIFF, (thandle_t) &client_data);
TIFFSetFileName(faxTIFF, (const char*)argv[optind]);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, xsize);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression_out);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric_out);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
switch (compression_out) {
/* g3 */
case COMPRESSION_CCITTFAX3:
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
group3options_out);
TIFFSetField(out, TIFFTAG_FAXMODE, mode);
rowsperstrip =
(defrowsperstrip)?defrowsperstrip:(uint32)-1L;
break;
/* g4 */
case COMPRESSION_CCITTFAX4:
TIFFSetField(out, TIFFTAG_GROUP4OPTIONS,
group4options_out);
TIFFSetField(out, TIFFTAG_FAXMODE, mode);
rowsperstrip =
(defrowsperstrip)?defrowsperstrip:(uint32)-1L;
break;
default:
rowsperstrip = (defrowsperstrip) ?
defrowsperstrip : TIFFDefaultStripSize(out, 0);
}
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder_out);
TIFFSetField(out, TIFFTAG_SOFTWARE, "fax2tiff");
TIFFSetField(out, TIFFTAG_XRESOLUTION, 204.0);
if (!stretch) {
TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &resY);
TIFFSetField(out, TIFFTAG_YRESOLUTION, resY);
} else
TIFFSetField(out, TIFFTAG_YRESOLUTION, 196.);
TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
TIFFSetField(out, TIFFTAG_PAGENUMBER, pn, npages);
if (!verbose)
whandler = TIFFSetWarningHandler(NULL);
rows = copyFaxFile(faxTIFF, out);
fclose(in);
if (!verbose)
(void) TIFFSetWarningHandler(whandler);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, rows);
if (verbose) {
fprintf(stderr, "%s:\n", argv[optind]);
fprintf(stderr, "%d rows in input\n", rows);
fprintf(stderr, "%ld total bad rows\n",
(long) badfaxlines);
fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun);
}
if (compression_out == COMPRESSION_CCITTFAX3 &&
mode == FAXMODE_CLASSF) {
TIFFSetField(out, TIFFTAG_BADFAXLINES, badfaxlines);
TIFFSetField(out, TIFFTAG_CLEANFAXDATA, badfaxlines ?
CLEANFAXDATA_REGENERATED : CLEANFAXDATA_CLEAN);
TIFFSetField(out, TIFFTAG_CONSECUTIVEBADFAXLINES, badfaxrun);
}
TIFFWriteDirectory(out);
}
TIFFClose(out);
_TIFFfree(rowbuf);
_TIFFfree(refbuf);
return (EXIT_SUCCESS);
}
int
copyFaxFile(TIFF* tifin, TIFF* tifout)
{
uint32 row;
uint32 linesize = TIFFhowmany8(xsize);
uint16 badrun;
int ok;
tifin->tif_rawdatasize = (tmsize_t)TIFFGetFileSize(tifin);
if (tifin->tif_rawdatasize == 0) {
TIFFError(tifin->tif_name, "Empty input file");
return (0);
}
tifin->tif_rawdata = _TIFFmalloc(tifin->tif_rawdatasize);
if (tifin->tif_rawdata == NULL) {
TIFFError(tifin->tif_name, "Not enough memory");
return (0);
}
if (!ReadOK(tifin, tifin->tif_rawdata, tifin->tif_rawdatasize)) {
TIFFError(tifin->tif_name, "Read error at scanline 0");
return (0);
}
tifin->tif_rawcp = tifin->tif_rawdata;
tifin->tif_rawcc = tifin->tif_rawdatasize;
(*tifin->tif_setupdecode)(tifin);
(*tifin->tif_predecode)(tifin, (tsample_t) 0);
tifin->tif_row = 0;
badfaxlines = 0;
badfaxrun = 0;
_TIFFmemset(refbuf, 0, linesize);
row = 0;
badrun = 0; /* current run of bad lines */
while (tifin->tif_rawcc > 0) {
ok = (*tifin->tif_decoderow)(tifin, (tdata_t) rowbuf,
linesize, 0);
if (!ok) {
badfaxlines++;
badrun++;
/* regenerate line from previous good line */
_TIFFmemcpy(rowbuf, refbuf, linesize);
} else {
if (badrun > badfaxrun)
badfaxrun = badrun;
badrun = 0;
_TIFFmemcpy(refbuf, rowbuf, linesize);
}
tifin->tif_row++;
if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
fprintf(stderr, "%s: Write error at row %ld.\n",
tifout->tif_name, (long) row);
break;
}
row++;
if (stretch) {
if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
fprintf(stderr, "%s: Write error at row %ld.\n",
tifout->tif_name, (long) row);
break;
}
row++;
}
}
if (badrun > badfaxrun)
badfaxrun = badrun;
_TIFFfree(tifin->tif_rawdata);
return (row);
}
char* stuff[] = {
"usage: fax2tiff [options] input.raw...",
"where options are:",
" -3 input data is G3-encoded [default]",
" -4 input data is G4-encoded",
" -U input data is uncompressed (G3 or G4)",
" -1 input data is 1D-encoded (G3 only) [default]",
" -2 input data is 2D-encoded (G3 only)",
" -P input is not EOL-aligned (G3 only) [default]",
" -A input is EOL-aligned (G3 only)",
" -M input data has MSB2LSB bit order",
" -L input data has LSB2MSB bit order [default]",
" -B input data has min 0 means black",
" -W input data has min 0 means white [default]",
" -R # input data has # resolution (lines/inch) [default is 196]",
" -X # input data has # width [default is 1728]",
"",
" -o out.tif write output to out.tif",
" -7 generate G3-encoded output [default]",
" -8 generate G4-encoded output",
" -u generate uncompressed output (G3 or G4)",
" -5 generate 1D-encoded output (G3 only)",
" -6 generate 2D-encoded output (G3 only) [default]",
" -p generate not EOL-aligned output (G3 only)",
" -a generate EOL-aligned output (G3 only) [default]",
" -c generate \"classic\" TIFF format",
" -f generate TIFF Class F (TIFF/F) format [default]",
" -m output fill order is MSB2LSB",
" -l output fill order is LSB2MSB [default]",
" -r # make each strip have no more than # rows",
" -s stretch image by duplicating scanlines",
" -v print information about conversion work",
" -z generate LZW compressed output",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(EXIT_FAILURE);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,454 @@
/* $Id: pal2rgb.c,v 1.15 2015-06-21 01:09:10 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffio.h"
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
static void usage(void);
static void cpTags(TIFF* in, TIFF* out);
static int
checkcmap(int n, uint16* r, uint16* g, uint16* b)
{
while (n-- > 0)
if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
return (16);
fprintf(stderr, "Warning, assuming 8-bit colormap.\n");
return (8);
}
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
#define CopyField3(tag, v1, v2, v3) \
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
static uint16 compression = (uint16) -1;
static uint16 predictor = 0;
static int quality = 75; /* JPEG quality */
static int jpegcolormode = JPEGCOLORMODE_RGB;
static int processCompressOptions(char*);
int
main(int argc, char* argv[])
{
uint16 bitspersample, shortv;
uint32 imagewidth, imagelength;
uint16 config = PLANARCONFIG_CONTIG;
uint32 rowsperstrip = (uint32) -1;
uint16 photometric = PHOTOMETRIC_RGB;
uint16 *rmap, *gmap, *bmap;
uint32 row;
int cmap = -1;
TIFF *in, *out;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
while ((c = getopt(argc, argv, "C:c:p:r:")) != -1)
switch (c) {
case 'C': /* force colormap interpretation */
cmap = atoi(optarg);
break;
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'p': /* planar configuration */
if (streq(optarg, "separate"))
config = PLANARCONFIG_SEPARATE;
else if (streq(optarg, "contig"))
config = PLANARCONFIG_CONTIG;
else
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind != 2)
usage();
in = TIFFOpen(argv[optind], "r");
if (in == NULL)
return (-1);
if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &shortv) ||
shortv != PHOTOMETRIC_PALETTE) {
fprintf(stderr, "%s: Expecting a palette image.\n",
argv[optind]);
return (-1);
}
if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
fprintf(stderr,
"%s: No colormap (not a valid palette image).\n",
argv[optind]);
return (-1);
}
bitspersample = 0;
TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
if (bitspersample != 8) {
fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n",
argv[optind]);
return (-1);
}
out = TIFFOpen(argv[optind+1], "w");
if (out == NULL)
return (-2);
cpTags(in, out);
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength);
if (compression != (uint16)-1)
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
else
TIFFGetField(in, TIFFTAG_COMPRESSION, &compression);
switch (compression) {
case COMPRESSION_JPEG:
if (jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
else
photometric = PHOTOMETRIC_RGB;
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip));
(void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
if (cmap == -1)
cmap = checkcmap(1<<bitspersample, rmap, gmap, bmap);
if (cmap == 16) {
/*
* Convert 16-bit colormap to 8-bit.
*/
int i;
for (i = (1<<bitspersample)-1; i >= 0; i--) {
#define CVT(x) (((x) * 255) / ((1L<<16)-1))
rmap[i] = CVT(rmap[i]);
gmap[i] = CVT(gmap[i]);
bmap[i] = CVT(bmap[i]);
}
}
{ unsigned char *ibuf, *obuf;
register unsigned char* pp;
register uint32 x;
ibuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(in));
obuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(out));
switch (config) {
case PLANARCONFIG_CONTIG:
for (row = 0; row < imagelength; row++) {
if (!TIFFReadScanline(in, ibuf, row, 0))
goto done;
pp = obuf;
for (x = 0; x < imagewidth; x++) {
*pp++ = (unsigned char) rmap[ibuf[x]];
*pp++ = (unsigned char) gmap[ibuf[x]];
*pp++ = (unsigned char) bmap[ibuf[x]];
}
if (!TIFFWriteScanline(out, obuf, row, 0))
goto done;
}
break;
case PLANARCONFIG_SEPARATE:
for (row = 0; row < imagelength; row++) {
if (!TIFFReadScanline(in, ibuf, row, 0))
goto done;
for (pp = obuf, x = 0; x < imagewidth; x++)
*pp++ = (unsigned char) rmap[ibuf[x]];
if (!TIFFWriteScanline(out, obuf, row, 0))
goto done;
for (pp = obuf, x = 0; x < imagewidth; x++)
*pp++ = (unsigned char) gmap[ibuf[x]];
if (!TIFFWriteScanline(out, obuf, row, 0))
goto done;
for (pp = obuf, x = 0; x < imagewidth; x++)
*pp++ = (unsigned char) bmap[ibuf[x]];
if (!TIFFWriteScanline(out, obuf, row, 0))
goto done;
}
break;
}
_TIFFfree(ibuf);
_TIFFfree(obuf);
}
done:
(void) TIFFClose(in);
(void) TIFFClose(out);
return (0);
}
static int
processCompressOptions(char* opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "jpeg", 4)) {
char* cp = strchr(opt, ':');
compression = COMPRESSION_JPEG;
while( cp )
{
if (isdigit((int)cp[1]))
quality = atoi(cp+1);
else if (cp[1] == 'r' )
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
cp = strchr(cp+1,':');
}
} else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_DEFLATE;
} else
return (0);
return (1);
}
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
#define CopyField2(tag, v1, v2) \
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
#define CopyField3(tag, v1, v2, v3) \
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
#define CopyField4(tag, v1, v2, v3, v4) \
if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
static void
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
{
switch (type) {
case TIFF_SHORT:
if (count == 1) {
uint16 shortv;
CopyField(tag, shortv);
} else if (count == 2) {
uint16 shortv1, shortv2;
CopyField2(tag, shortv1, shortv2);
} else if (count == 4) {
uint16 *tr, *tg, *tb, *ta;
CopyField4(tag, tr, tg, tb, ta);
} else if (count == (uint16) -1) {
uint16 shortv1;
uint16* shortav;
CopyField2(tag, shortv1, shortav);
}
break;
case TIFF_LONG:
{ uint32 longv;
CopyField(tag, longv);
}
break;
case TIFF_RATIONAL:
if (count == 1) {
float floatv;
CopyField(tag, floatv);
} else if (count == (uint16) -1) {
float* floatav;
CopyField(tag, floatav);
}
break;
case TIFF_ASCII:
{ char* stringv;
CopyField(tag, stringv);
}
break;
case TIFF_DOUBLE:
if (count == 1) {
double doublev;
CopyField(tag, doublev);
} else if (count == (uint16) -1) {
double* doubleav;
CopyField(tag, doubleav);
}
break;
default:
TIFFError(TIFFFileName(in),
"Data type %d is not supported, tag %d skipped.",
tag, type);
}
}
#undef CopyField4
#undef CopyField3
#undef CopyField2
#undef CopyField
static struct cpTag {
uint16 tag;
uint16 count;
TIFFDataType type;
} tags[] = {
{ TIFFTAG_IMAGEWIDTH, 1, TIFF_LONG },
{ TIFFTAG_IMAGELENGTH, 1, TIFF_LONG },
{ TIFFTAG_BITSPERSAMPLE, 1, TIFF_SHORT },
{ TIFFTAG_COMPRESSION, 1, TIFF_SHORT },
{ TIFFTAG_FILLORDER, 1, TIFF_SHORT },
{ TIFFTAG_ROWSPERSTRIP, 1, TIFF_LONG },
{ TIFFTAG_GROUP3OPTIONS, 1, TIFF_LONG },
{ TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
{ TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
{ TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
{ TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
{ TIFFTAG_MAKE, 1, TIFF_ASCII },
{ TIFFTAG_MODEL, 1, TIFF_ASCII },
{ TIFFTAG_ORIENTATION, 1, TIFF_SHORT },
{ TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
{ TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
{ TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
{ TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
{ TIFFTAG_PAGENAME, 1, TIFF_ASCII },
{ TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
{ TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
{ TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG },
{ TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
{ TIFFTAG_PAGENUMBER, 2, TIFF_SHORT },
{ TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
{ TIFFTAG_DATETIME, 1, TIFF_ASCII },
{ TIFFTAG_ARTIST, 1, TIFF_ASCII },
{ TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
{ TIFFTAG_WHITEPOINT, 2, TIFF_RATIONAL },
{ TIFFTAG_PRIMARYCHROMATICITIES, (uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
{ TIFFTAG_BADFAXLINES, 1, TIFF_LONG },
{ TIFFTAG_CLEANFAXDATA, 1, TIFF_SHORT },
{ TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG },
{ TIFFTAG_INKSET, 1, TIFF_SHORT },
/*{ TIFFTAG_INKNAMES, 1, TIFF_ASCII },*/ /* Needs much more complicated logic. See tiffcp */
{ TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
{ TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
{ TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
{ TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
{ TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
{ TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
};
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
static void
cpTags(TIFF* in, TIFF* out)
{
struct cpTag *p;
for (p = tags; p < &tags[NTAGS]; p++)
{
if( p->tag == TIFFTAG_GROUP3OPTIONS )
{
uint16 compression;
if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) ||
compression != COMPRESSION_CCITTFAX3 )
continue;
}
if( p->tag == TIFFTAG_GROUP4OPTIONS )
{
uint16 compression;
if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) ||
compression != COMPRESSION_CCITTFAX4 )
continue;
}
cpTag(in, out, p->tag, p->count, p->type);
}
}
#undef NTAGS
char* stuff[] = {
"usage: pal2rgb [options] input.tif output.tif",
"where options are:",
" -p contig pack samples contiguously (e.g. RGBRGB...)",
" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
" -r # make each strip have no more than # rows",
" -C 8 assume 8-bit colormap values (instead of 16-bit)",
" -C 16 assume 16-bit colormap values",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,398 @@
/* $Id: ppm2tiff.c,v 1.19 2015-06-21 01:09:10 bfriesen Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffio.h"
#ifndef HAVE_GETOPT
extern int getopt(int, char**, char*);
#endif
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
static uint16 compression = COMPRESSION_PACKBITS;
static uint16 predictor = 0;
static int quality = 75; /* JPEG quality */
static int jpegcolormode = JPEGCOLORMODE_RGB;
static uint32 g3opts;
static void usage(void);
static int processCompressOptions(char*);
static void
BadPPM(char* file)
{
fprintf(stderr, "%s: Not a PPM file.\n", file);
exit(-2);
}
#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2)
{
if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
return 0;
return m1 * m2;
}
int
main(int argc, char* argv[])
{
uint16 photometric = 0;
uint32 rowsperstrip = (uint32) -1;
double resolution = -1;
unsigned char *buf = NULL;
tmsize_t linebytes = 0;
uint16 spp = 1;
uint16 bpp = 8;
TIFF *out;
FILE *in;
unsigned int w, h, prec, row;
char *infile;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
tmsize_t scanline_size;
if (argc < 2) {
fprintf(stderr, "%s: Too few arguments\n", argv[0]);
usage();
}
while ((c = getopt(argc, argv, "c:r:R:")) != -1)
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case 'R': /* resolution */
resolution = atof(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (optind + 2 < argc) {
fprintf(stderr, "%s: Too many arguments\n", argv[0]);
usage();
}
/*
* If only one file is specified, read input from
* stdin; otherwise usage is: ppm2tiff input output.
*/
if (argc - optind > 1) {
infile = argv[optind++];
in = fopen(infile, "rb");
if (in == NULL) {
fprintf(stderr, "%s: Can not open.\n", infile);
return (-1);
}
} else {
infile = "<stdin>";
in = stdin;
#if defined(HAVE_SETMODE) && defined(O_BINARY)
setmode(fileno(stdin), O_BINARY);
#endif
}
if (fgetc(in) != 'P')
BadPPM(infile);
switch (fgetc(in)) {
case '4': /* it's a PBM file */
bpp = 1;
spp = 1;
photometric = PHOTOMETRIC_MINISWHITE;
break;
case '5': /* it's a PGM file */
bpp = 8;
spp = 1;
photometric = PHOTOMETRIC_MINISBLACK;
break;
case '6': /* it's a PPM file */
bpp = 8;
spp = 3;
photometric = PHOTOMETRIC_RGB;
if (compression == COMPRESSION_JPEG &&
jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
break;
default:
BadPPM(infile);
}
/* Parse header */
while(1) {
if (feof(in))
BadPPM(infile);
c = fgetc(in);
/* Skip whitespaces (blanks, TABs, CRs, LFs) */
if (strchr(" \t\r\n", c))
continue;
/* Check for comment line */
if (c == '#') {
do {
c = fgetc(in);
} while(!(strchr("\r\n", c) || feof(in)));
continue;
}
ungetc(c, in);
break;
}
switch (bpp) {
case 1:
if (fscanf(in, " %u %u", &w, &h) != 2)
BadPPM(infile);
if (fgetc(in) != '\n')
BadPPM(infile);
break;
case 8:
if (fscanf(in, " %u %u %u", &w, &h, &prec) != 3)
BadPPM(infile);
if (fgetc(in) != '\n' || prec != 255)
BadPPM(infile);
break;
}
out = TIFFOpen(argv[optind], "w");
if (out == NULL)
return (-4);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) w);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) h);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
switch (compression) {
case COMPRESSION_JPEG:
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
case COMPRESSION_CCITTFAX3:
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
break;
}
switch (bpp) {
case 1:
/* if round-up overflows, result will be zero, OK */
linebytes = (multiply_ms(spp, w) + (8 - 1)) / 8;
if (rowsperstrip == (uint32) -1) {
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h);
} else {
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
}
break;
case 8:
linebytes = multiply_ms(spp, w);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
break;
}
if (linebytes == 0) {
fprintf(stderr, "%s: scanline size overflow\n", infile);
(void) TIFFClose(out);
exit(-2);
}
scanline_size = TIFFScanlineSize(out);
if (scanline_size == 0) {
/* overflow - TIFFScanlineSize already printed a message */
(void) TIFFClose(out);
exit(-2);
}
if (scanline_size < linebytes)
buf = (unsigned char *)_TIFFmalloc(linebytes);
else
buf = (unsigned char *)_TIFFmalloc(scanline_size);
if (buf == NULL) {
fprintf(stderr, "%s: Not enough memory\n", infile);
(void) TIFFClose(out);
exit(-2);
}
if (resolution > 0) {
TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution);
TIFFSetField(out, TIFFTAG_YRESOLUTION, resolution);
TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
}
for (row = 0; row < h; row++) {
if (fread(buf, linebytes, 1, in) != 1) {
fprintf(stderr, "%s: scanline %lu: Read error.\n",
infile, (unsigned long) row);
break;
}
if (TIFFWriteScanline(out, buf, row, 0) < 0)
break;
}
(void) TIFFClose(out);
if (buf)
_TIFFfree(buf);
return (0);
}
static void
processG3Options(char* cp)
{
g3opts = 0;
if( (cp = strchr(cp, ':')) ) {
do {
cp++;
if (strneq(cp, "1d", 2))
g3opts &= ~GROUP3OPT_2DENCODING;
else if (strneq(cp, "2d", 2))
g3opts |= GROUP3OPT_2DENCODING;
else if (strneq(cp, "fill", 4))
g3opts |= GROUP3OPT_FILLBITS;
else
usage();
} while( (cp = strchr(cp, ':')) );
}
}
static int
processCompressOptions(char* opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "jpeg", 4)) {
char* cp = strchr(opt, ':');
compression = COMPRESSION_JPEG;
while (cp)
{
if (isdigit((int)cp[1]))
quality = atoi(cp+1);
else if (cp[1] == 'r' )
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
cp = strchr(cp+1,':');
}
} else if (strneq(opt, "g3", 2)) {
processG3Options(opt);
compression = COMPRESSION_CCITTFAX3;
} else if (streq(opt, "g4")) {
compression = COMPRESSION_CCITTFAX4;
} else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_DEFLATE;
} else
return (0);
return (1);
}
char* stuff[] = {
"usage: ppm2tiff [options] input.ppm output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
" -R # set x&y resolution (dpi)",
"",
" -c jpeg[:opts] compress output with JPEG encoding",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c packbits compress output with packbits encoding (the default)",
" -c g3[:opts] compress output with CCITT Group 3 encoding",
" -c g4 compress output with CCITT Group 4 encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,690 @@
/* $Id: raw2tiff.c,v 1.29 2017-01-14 13:12:33 erouault Exp $
*
* Project: libtiff tools
* Purpose: Convert raw byte sequences in TIFF images
* Author: Andrey Kiselev, dron@ak4719.spb.edu
*
******************************************************************************
* Copyright (c) 2002, Andrey Kiselev <dron@ak4719.spb.edu>
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <math.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#if HAVE_FCNTL_H
# include <fcntl.h>
#endif
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_IO_H
# include <io.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffiop.h"
#include "tiffio.h"
#ifndef HAVE_GETOPT
extern int getopt(int, char**, char*);
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif
typedef enum {
PIXEL,
BAND
} InterleavingType;
static uint16 compression = (uint16) -1;
static int jpegcolormode = JPEGCOLORMODE_RGB;
static int quality = 75; /* JPEG quality */
static uint16 predictor = 0;
static void swapBytesInScanline(void *, uint32, TIFFDataType);
static int guessSize(int, TIFFDataType, _TIFF_off_t, uint32, int,
uint32 *, uint32 *);
static double correlation(void *, void *, uint32, TIFFDataType);
static void usage(void);
static int processCompressOptions(char*);
int
main(int argc, char* argv[])
{
uint32 width = 0, length = 0, linebytes, bufsize;
uint32 nbands = 1; /* number of bands in input image*/
_TIFF_off_t hdr_size = 0; /* size of the header to skip */
TIFFDataType dtype = TIFF_BYTE;
int16 depth = 1; /* bytes per pixel in input image */
int swab = 0; /* byte swapping flag */
InterleavingType interleaving = 0; /* interleaving type flag */
uint32 rowsperstrip = (uint32) -1;
uint16 photometric = PHOTOMETRIC_MINISBLACK;
uint16 config = PLANARCONFIG_CONTIG;
uint16 fillorder = FILLORDER_LSB2MSB;
int fd;
char *outfilename = NULL;
TIFF *out;
uint32 row, col, band;
int c;
unsigned char *buf = NULL, *buf1 = NULL;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
while ((c = getopt(argc, argv, "c:r:H:w:l:b:d:LMp:si:o:h")) != -1) {
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case 'H': /* size of input image file header */
hdr_size = atoi(optarg);
break;
case 'w': /* input image width */
width = atoi(optarg);
break;
case 'l': /* input image length */
length = atoi(optarg);
break;
case 'b': /* number of bands in input image */
nbands = atoi(optarg);
break;
case 'd': /* type of samples in input image */
if (strncmp(optarg, "byte", 4) == 0)
dtype = TIFF_BYTE;
else if (strncmp(optarg, "short", 5) == 0)
dtype = TIFF_SHORT;
else if (strncmp(optarg, "long", 4) == 0)
dtype = TIFF_LONG;
else if (strncmp(optarg, "sbyte", 5) == 0)
dtype = TIFF_SBYTE;
else if (strncmp(optarg, "sshort", 6) == 0)
dtype = TIFF_SSHORT;
else if (strncmp(optarg, "slong", 5) == 0)
dtype = TIFF_SLONG;
else if (strncmp(optarg, "float", 5) == 0)
dtype = TIFF_FLOAT;
else if (strncmp(optarg, "double", 6) == 0)
dtype = TIFF_DOUBLE;
else
dtype = TIFF_BYTE;
depth = TIFFDataWidth(dtype);
break;
case 'L': /* input has lsb-to-msb fillorder */
fillorder = FILLORDER_LSB2MSB;
break;
case 'M': /* input has msb-to-lsb fillorder */
fillorder = FILLORDER_MSB2LSB;
break;
case 'p': /* photometric interpretation */
if (strncmp(optarg, "miniswhite", 10) == 0)
photometric = PHOTOMETRIC_MINISWHITE;
else if (strncmp(optarg, "minisblack", 10) == 0)
photometric = PHOTOMETRIC_MINISBLACK;
else if (strncmp(optarg, "rgb", 3) == 0)
photometric = PHOTOMETRIC_RGB;
else if (strncmp(optarg, "cmyk", 4) == 0)
photometric = PHOTOMETRIC_SEPARATED;
else if (strncmp(optarg, "ycbcr", 5) == 0)
photometric = PHOTOMETRIC_YCBCR;
else if (strncmp(optarg, "cielab", 6) == 0)
photometric = PHOTOMETRIC_CIELAB;
else if (strncmp(optarg, "icclab", 6) == 0)
photometric = PHOTOMETRIC_ICCLAB;
else if (strncmp(optarg, "itulab", 6) == 0)
photometric = PHOTOMETRIC_ITULAB;
else
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 's': /* do we need to swap bytes? */
swab = 1;
break;
case 'i': /* type of interleaving */
if (strncmp(optarg, "pixel", 4) == 0)
interleaving = PIXEL;
else if (strncmp(optarg, "band", 6) == 0)
interleaving = BAND;
else
interleaving = 0;
break;
case 'o':
outfilename = optarg;
break;
case 'h':
usage();
default:
break;
}
}
if (argc - optind < 2)
usage();
fd = open(argv[optind], O_RDONLY|O_BINARY, 0);
if (fd < 0) {
fprintf(stderr, "%s: %s: Cannot open input file.\n",
argv[0], argv[optind]);
return (-1);
}
if (guessSize(fd, dtype, hdr_size, nbands, swab, &width, &length) < 0)
return 1;
if (outfilename == NULL)
outfilename = argv[optind+1];
out = TIFFOpen(outfilename, "w");
if (out == NULL) {
fprintf(stderr, "%s: %s: Cannot open file for output.\n",
argv[0], outfilename);
return (-1);
}
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, nbands);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, depth * 8);
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
switch (dtype) {
case TIFF_BYTE:
case TIFF_SHORT:
case TIFF_LONG:
TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
break;
case TIFF_SBYTE:
case TIFF_SSHORT:
case TIFF_SLONG:
TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
break;
case TIFF_FLOAT:
case TIFF_DOUBLE:
TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
break;
default:
TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_VOID);
break;
}
if (compression == (uint16) -1)
compression = COMPRESSION_PACKBITS;
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
switch (compression) {
case COMPRESSION_JPEG:
if (photometric == PHOTOMETRIC_RGB
&& jpegcolormode == JPEGCOLORMODE_RGB)
photometric = PHOTOMETRIC_YCBCR;
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
switch(interleaving) {
case BAND: /* band interleaved data */
linebytes = width * depth;
buf = (unsigned char *)_TIFFmalloc(linebytes);
break;
case PIXEL: /* pixel interleaved data */
default:
linebytes = width * nbands * depth;
break;
}
bufsize = width * nbands * depth;
buf1 = (unsigned char *)_TIFFmalloc(bufsize);
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
if (rowsperstrip > length) {
rowsperstrip = length;
}
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip );
_TIFF_lseek_f(fd, hdr_size, SEEK_SET); /* Skip the file header */
for (row = 0; row < length; row++) {
switch(interleaving) {
case BAND: /* band interleaved data */
for (band = 0; band < nbands; band++) {
if (_TIFF_lseek_f(fd,
hdr_size + (length*band+row)*linebytes,
SEEK_SET) == (_TIFF_off_t)-1) {
fprintf(stderr,
"%s: %s: scanline %lu: seek error.\n",
argv[0], argv[optind],
(unsigned long) row);
break;
}
if (read(fd, buf, linebytes) < 0) {
fprintf(stderr,
"%s: %s: scanline %lu: Read error.\n",
argv[0], argv[optind],
(unsigned long) row);
break;
}
if (swab) /* Swap bytes if needed */
swapBytesInScanline(buf, width, dtype);
for (col = 0; col < width; col++)
memcpy(buf1 + (col*nbands+band)*depth,
buf + col * depth, depth);
}
break;
case PIXEL: /* pixel interleaved data */
default:
if (read(fd, buf1, bufsize) < 0) {
fprintf(stderr,
"%s: %s: scanline %lu: Read error.\n",
argv[0], argv[optind],
(unsigned long) row);
break;
}
if (swab) /* Swap bytes if needed */
swapBytesInScanline(buf1, width, dtype);
break;
}
if (TIFFWriteScanline(out, buf1, row, 0) < 0) {
fprintf(stderr, "%s: %s: scanline %lu: Write error.\n",
argv[0], outfilename, (unsigned long) row);
break;
}
}
if (buf)
_TIFFfree(buf);
if (buf1)
_TIFFfree(buf1);
TIFFClose(out);
return (0);
}
static void
swapBytesInScanline(void *buf, uint32 width, TIFFDataType dtype)
{
switch (dtype) {
case TIFF_SHORT:
case TIFF_SSHORT:
TIFFSwabArrayOfShort((uint16*)buf,
(unsigned long)width);
break;
case TIFF_LONG:
case TIFF_SLONG:
TIFFSwabArrayOfLong((uint32*)buf,
(unsigned long)width);
break;
/* case TIFF_FLOAT: */ /* FIXME */
case TIFF_DOUBLE:
TIFFSwabArrayOfDouble((double*)buf,
(unsigned long)width);
break;
default:
break;
}
}
static int
guessSize(int fd, TIFFDataType dtype, _TIFF_off_t hdr_size, uint32 nbands,
int swab, uint32 *width, uint32 *length)
{
const float longt = 40.0; /* maximum possible height/width ratio */
char *buf1, *buf2;
_TIFF_stat_s filestat;
uint32 w, h, scanlinesize, imagesize;
uint32 depth = TIFFDataWidth(dtype);
float cor_coef = 0, tmp;
if (_TIFF_fstat_f(fd, &filestat) == -1) {
fprintf(stderr, "Failed to obtain file size.\n");
return -1;
}
if (filestat.st_size < hdr_size) {
fprintf(stderr, "Too large header size specified.\n");
return -1;
}
imagesize = (filestat.st_size - hdr_size) / nbands / depth;
if (*width != 0 && *length == 0) {
fprintf(stderr, "Image height is not specified.\n");
*length = imagesize / *width;
fprintf(stderr, "Height is guessed as %lu.\n",
(unsigned long)*length);
return 1;
} else if (*width == 0 && *length != 0) {
fprintf(stderr, "Image width is not specified.\n");
*width = imagesize / *length;
fprintf(stderr, "Width is guessed as %lu.\n",
(unsigned long)*width);
return 1;
} else if (*width == 0 && *length == 0) {
unsigned int fail = 0;
fprintf(stderr, "Image width and height are not specified.\n");
w = (uint32) sqrt(imagesize / longt);
if( w == 0 )
{
fprintf(stderr, "Too small image size.\n");
return -1;
}
for (;
w < sqrt(imagesize * longt);
w++) {
if (imagesize % w == 0) {
scanlinesize = w * depth;
buf1 = _TIFFmalloc(scanlinesize);
buf2 = _TIFFmalloc(scanlinesize);
h = imagesize / w;
do {
if (_TIFF_lseek_f(fd, hdr_size + (int)(h/2)*scanlinesize,
SEEK_SET) == (_TIFF_off_t)-1) {
fprintf(stderr, "seek error.\n");
fail=1;
break;
}
if (read(fd, buf1, scanlinesize) !=
(long) scanlinesize) {
fprintf(stderr, "read error.\n");
fail=1;
break;
}
if (read(fd, buf2, scanlinesize) !=
(long) scanlinesize) {
fprintf(stderr, "read error.\n");
fail=1;
break;
}
if (swab) {
swapBytesInScanline(buf1, w, dtype);
swapBytesInScanline(buf2, w, dtype);
}
tmp = (float) fabs(correlation(buf1, buf2,
w, dtype));
if (tmp > cor_coef) {
cor_coef = tmp;
*width = w, *length = h;
}
} while (0);
_TIFFfree(buf1);
_TIFFfree(buf2);
}
}
if (fail) {
return -1;
}
fprintf(stderr,
"Width is guessed as %lu, height is guessed as %lu.\n",
(unsigned long)*width, (unsigned long)*length);
return 1;
} else {
if (filestat.st_size<(_TIFF_off_t)(hdr_size+(*width)*(*length)*nbands*depth)) {
fprintf(stderr, "Input file too small.\n");
return -1;
}
}
return 1;
}
/* Calculate correlation coefficient between two numeric vectors */
static double
correlation(void *buf1, void *buf2, uint32 n_elem, TIFFDataType dtype)
{
double X, Y, M1 = 0.0, M2 = 0.0, D1 = 0.0, D2 = 0.0, K = 0.0;
uint32 i;
switch (dtype) {
case TIFF_BYTE:
default:
for (i = 0; i < n_elem; i++) {
X = ((unsigned char *)buf1)[i];
Y = ((unsigned char *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
case TIFF_SBYTE:
for (i = 0; i < n_elem; i++) {
X = ((signed char *)buf1)[i];
Y = ((signed char *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
case TIFF_SHORT:
for (i = 0; i < n_elem; i++) {
X = ((uint16 *)buf1)[i];
Y = ((uint16 *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
case TIFF_SSHORT:
for (i = 0; i < n_elem; i++) {
X = ((int16 *)buf1)[i];
Y = ((int16 *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
case TIFF_LONG:
for (i = 0; i < n_elem; i++) {
X = ((uint32 *)buf1)[i];
Y = ((uint32 *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
case TIFF_SLONG:
for (i = 0; i < n_elem; i++) {
X = ((int32 *)buf1)[i];
Y = ((int32 *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
case TIFF_FLOAT:
for (i = 0; i < n_elem; i++) {
X = ((float *)buf1)[i];
Y = ((float *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
case TIFF_DOUBLE:
for (i = 0; i < n_elem; i++) {
X = ((double *)buf1)[i];
Y = ((double *)buf2)[i];
M1 += X, M2 += Y;
D1 += X * X, D2 += Y * Y;
K += X * Y;
}
break;
}
M1 /= n_elem;
M2 /= n_elem;
D1 -= M1 * M1 * n_elem;
D2 -= M2 * M2 * n_elem;
K = (K - M1 * M2 * n_elem) / sqrt(D1 * D2);
return K;
}
static int
processCompressOptions(char* opt)
{
if (strcmp(opt, "none") == 0)
compression = COMPRESSION_NONE;
else if (strcmp(opt, "packbits") == 0)
compression = COMPRESSION_PACKBITS;
else if (strncmp(opt, "jpeg", 4) == 0) {
char* cp = strchr(opt, ':');
compression = COMPRESSION_JPEG;
while( cp )
{
if (isdigit((int)cp[1]))
quality = atoi(cp+1);
else if (cp[1] == 'r' )
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
cp = strchr(cp+1,':');
}
} else if (strncmp(opt, "lzw", 3) == 0) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strncmp(opt, "zip", 3) == 0) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_DEFLATE;
} else
return (0);
return (1);
}
static char* stuff[] = {
"raw2tiff --- tool for converting raw byte sequences in TIFF images",
"usage: raw2tiff [options] input.raw output.tif",
"where options are:",
" -L input data has LSB2MSB bit order (default)",
" -M input data has MSB2LSB bit order",
" -r # make each strip have no more than # rows",
" -H # size of input image file header in bytes (0 by default)",
" -w # width of input image in pixels",
" -l # length of input image in lines",
" -b # number of bands in input image (1 by default)",
"",
" -d data_type type of samples in input image",
"where data_type may be:",
" byte 8-bit unsigned integer (default)",
" short 16-bit unsigned integer",
" long 32-bit unsigned integer",
" sbyte 8-bit signed integer",
" sshort 16-bit signed integer",
" slong 32-bit signed integer",
" float 32-bit IEEE floating point",
" double 64-bit IEEE floating point",
"",
" -p photo photometric interpretation (color space) of the input image",
"where photo may be:",
" miniswhite white color represented with 0 value",
" minisblack black color represented with 0 value (default)",
" rgb image has RGB color model",
" cmyk image has CMYK (separated) color model",
" ycbcr image has YCbCr color model",
" cielab image has CIE L*a*b color model",
" icclab image has ICC L*a*b color model",
" itulab image has ITU L*a*b color model",
"",
" -s swap bytes fetched from input file",
"",
" -i config type of samples interleaving in input image",
"where config may be:",
" pixel pixel interleaved data (default)",
" band band interleaved data",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c jpeg[:opts] compress output with JPEG encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"JPEG options:",
" # set compression quality level (0-100, default 75)",
" r output color image as RGB rather than YCbCr",
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
" -o out.tif write output to out.tif",
" -h this help message",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,397 @@
/* $Id: rgb2ycbcr.c,v 1.17 2016-08-15 21:26:56 erouault Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffiop.h"
#include "tiffio.h"
#define streq(a,b) (strcmp(a,b) == 0)
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
#define roundup(x, y) (howmany(x,y)*((uint32)(y)))
#define LumaRed ycbcrCoeffs[0]
#define LumaGreen ycbcrCoeffs[1]
#define LumaBlue ycbcrCoeffs[2]
uint16 compression = COMPRESSION_PACKBITS;
uint32 rowsperstrip = (uint32) -1;
uint16 horizSubSampling = 2; /* YCbCr horizontal subsampling */
uint16 vertSubSampling = 2; /* YCbCr vertical subsampling */
float ycbcrCoeffs[3] = { .299F, .587F, .114F };
/* default coding range is CCIR Rec 601-1 with no headroom/footroom */
float refBlackWhite[6] = { 0.F, 255.F, 128.F, 255.F, 128.F, 255.F };
static int tiffcvt(TIFF* in, TIFF* out);
static void usage(int code);
static void setupLumaTables(void);
int
main(int argc, char* argv[])
{
TIFF *in, *out;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char *optarg;
#endif
while ((c = getopt(argc, argv, "c:h:r:v:z")) != -1)
switch (c) {
case 'c':
if (streq(optarg, "none"))
compression = COMPRESSION_NONE;
else if (streq(optarg, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (streq(optarg, "lzw"))
compression = COMPRESSION_LZW;
else if (streq(optarg, "jpeg"))
compression = COMPRESSION_JPEG;
else if (streq(optarg, "zip"))
compression = COMPRESSION_ADOBE_DEFLATE;
else
usage(-1);
break;
case 'h':
horizSubSampling = atoi(optarg);
if( horizSubSampling != 1 && horizSubSampling != 2 && horizSubSampling != 4 )
usage(-1);
break;
case 'v':
vertSubSampling = atoi(optarg);
if( vertSubSampling != 1 && vertSubSampling != 2 && vertSubSampling != 4 )
usage(-1);
break;
case 'r':
rowsperstrip = atoi(optarg);
break;
case 'z': /* CCIR Rec 601-1 w/ headroom/footroom */
refBlackWhite[0] = 16.;
refBlackWhite[1] = 235.;
refBlackWhite[2] = 128.;
refBlackWhite[3] = 240.;
refBlackWhite[4] = 128.;
refBlackWhite[5] = 240.;
break;
case '?':
usage(0);
/*NOTREACHED*/
}
if (argc - optind < 2)
usage(-1);
out = TIFFOpen(argv[argc-1], "w");
if (out == NULL)
return (-2);
setupLumaTables();
for (; optind < argc-1; optind++) {
in = TIFFOpen(argv[optind], "r");
if (in != NULL) {
do {
if (!tiffcvt(in, out) ||
!TIFFWriteDirectory(out)) {
(void) TIFFClose(out);
return (1);
}
} while (TIFFReadDirectory(in));
(void) TIFFClose(in);
}
}
(void) TIFFClose(out);
return (0);
}
float *lumaRed;
float *lumaGreen;
float *lumaBlue;
float D1, D2;
int Yzero;
static float*
setupLuma(float c)
{
float *v = (float *)_TIFFmalloc(256 * sizeof (float));
int i;
for (i = 0; i < 256; i++)
v[i] = c * i;
return (v);
}
static unsigned
V2Code(float f, float RB, float RW, int CR)
{
unsigned int c = (unsigned int)((((f)*(RW-RB)/CR)+RB)+.5);
return (c > 255 ? 255 : c);
}
static void
setupLumaTables(void)
{
lumaRed = setupLuma(LumaRed);
lumaGreen = setupLuma(LumaGreen);
lumaBlue = setupLuma(LumaBlue);
D1 = 1.F/(2.F - 2.F*LumaBlue);
D2 = 1.F/(2.F - 2.F*LumaRed);
Yzero = V2Code(0, refBlackWhite[0], refBlackWhite[1], 255);
}
static void
cvtClump(unsigned char* op, uint32* raster, uint32 ch, uint32 cw, uint32 w)
{
float Y, Cb = 0, Cr = 0;
uint32 j, k;
/*
* Convert ch-by-cw block of RGB
* to YCbCr and sample accordingly.
*/
for (k = 0; k < ch; k++) {
for (j = 0; j < cw; j++) {
uint32 RGB = (raster - k*w)[j];
Y = lumaRed[TIFFGetR(RGB)] +
lumaGreen[TIFFGetG(RGB)] +
lumaBlue[TIFFGetB(RGB)];
/* accumulate chrominance */
Cb += (TIFFGetB(RGB) - Y) * D1;
Cr += (TIFFGetR(RGB) - Y) * D2;
/* emit luminence */
*op++ = V2Code(Y,
refBlackWhite[0], refBlackWhite[1], 255);
}
for (; j < horizSubSampling; j++)
*op++ = Yzero;
}
for (; k < vertSubSampling; k++) {
for (j = 0; j < horizSubSampling; j++)
*op++ = Yzero;
}
/* emit sampled chrominance values */
*op++ = V2Code(Cb / (ch*cw), refBlackWhite[2], refBlackWhite[3], 127);
*op++ = V2Code(Cr / (ch*cw), refBlackWhite[4], refBlackWhite[5], 127);
}
#undef LumaRed
#undef LumaGreen
#undef LumaBlue
#undef V2Code
/*
* Convert a strip of RGB data to YCbCr and
* sample to generate the output data.
*/
static void
cvtStrip(unsigned char* op, uint32* raster, uint32 nrows, uint32 width)
{
uint32 x;
int clumpSize = vertSubSampling * horizSubSampling + 2;
uint32 *tp;
for (; nrows >= vertSubSampling; nrows -= vertSubSampling) {
tp = raster;
for (x = width; x >= horizSubSampling; x -= horizSubSampling) {
cvtClump(op, tp,
vertSubSampling, horizSubSampling, width);
op += clumpSize;
tp += horizSubSampling;
}
if (x > 0) {
cvtClump(op, tp, vertSubSampling, x, width);
op += clumpSize;
}
raster -= vertSubSampling*width;
}
if (nrows > 0) {
tp = raster;
for (x = width; x >= horizSubSampling; x -= horizSubSampling) {
cvtClump(op, tp, nrows, horizSubSampling, width);
op += clumpSize;
tp += horizSubSampling;
}
if (x > 0)
cvtClump(op, tp, nrows, x, width);
}
}
static int
cvtRaster(TIFF* tif, uint32* raster, uint32 width, uint32 height)
{
uint32 y;
tstrip_t strip = 0;
tsize_t cc, acc;
unsigned char* buf;
uint32 rwidth = roundup(width, horizSubSampling);
uint32 rheight = roundup(height, vertSubSampling);
uint32 nrows = (rowsperstrip > rheight ? rheight : rowsperstrip);
uint32 rnrows = roundup(nrows,vertSubSampling);
cc = rnrows*rwidth +
2*((rnrows*rwidth) / (horizSubSampling*vertSubSampling));
buf = (unsigned char*)_TIFFmalloc(cc);
// FIXME unchecked malloc
for (y = height; (int32) y > 0; y -= nrows) {
uint32 nr = (y > nrows ? nrows : y);
cvtStrip(buf, raster + (y-1)*width, nr, width);
nr = roundup(nr, vertSubSampling);
acc = nr*rwidth +
2*((nr*rwidth)/(horizSubSampling*vertSubSampling));
if (!TIFFWriteEncodedStrip(tif, strip++, buf, acc)) {
_TIFFfree(buf);
return (0);
}
}
_TIFFfree(buf);
return (1);
}
static int
tiffcvt(TIFF* in, TIFF* out)
{
uint32 width, height; /* image width & height */
uint32* raster; /* retrieve RGBA image */
uint16 shortv;
float floatv;
char *stringv;
uint32 longv;
int result;
size_t pixel_count;
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
pixel_count = width * height;
/* XXX: Check the integer overflow. */
if (!width || !height || pixel_count / width != height) {
TIFFError(TIFFFileName(in),
"Malformed input file; "
"can't allocate buffer for raster of %lux%lu size",
(unsigned long)width, (unsigned long)height);
return 0;
}
raster = (uint32*)_TIFFCheckMalloc(in, pixel_count, sizeof(uint32),
"raster buffer");
if (raster == 0) {
TIFFError(TIFFFileName(in),
"Failed to allocate buffer (%lu elements of %lu each)",
(unsigned long)pixel_count,
(unsigned long)sizeof(uint32));
return (0);
}
if (!TIFFReadRGBAImage(in, width, height, raster, 0)) {
_TIFFfree(raster);
return (0);
}
CopyField(TIFFTAG_SUBFILETYPE, longv);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
if (compression == COMPRESSION_JPEG)
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW);
CopyField(TIFFTAG_FILLORDER, shortv);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
CopyField(TIFFTAG_XRESOLUTION, floatv);
CopyField(TIFFTAG_YRESOLUTION, floatv);
CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
{ char buf[2048];
char *cp = strrchr(TIFFFileName(in), '/');
snprintf(buf, sizeof(buf), "YCbCr conversion of %s",
cp ? cp+1 : TIFFFileName(in));
TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, buf);
}
TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion());
CopyField(TIFFTAG_DOCUMENTNAME, stringv);
TIFFSetField(out, TIFFTAG_REFERENCEBLACKWHITE, refBlackWhite);
TIFFSetField(out, TIFFTAG_YCBCRSUBSAMPLING,
horizSubSampling, vertSubSampling);
TIFFSetField(out, TIFFTAG_YCBCRPOSITIONING, YCBCRPOSITION_CENTERED);
TIFFSetField(out, TIFFTAG_YCBCRCOEFFICIENTS, ycbcrCoeffs);
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
result = cvtRaster(out, raster, width, height);
_TIFFfree(raster);
return result;
}
char* stuff[] = {
"usage: rgb2ycbcr [-c comp] [-r rows] [-h N] [-v N] input... output\n",
"where comp is one of the following compression algorithms:\n",
" jpeg\t\tJPEG encoding\n",
" lzw\t\tLempel-Ziv & Welch encoding\n",
" zip\t\tdeflate encoding\n",
" packbits\tPackBits encoding (default)\n",
" none\t\tno compression\n",
"and the other options are:\n",
" -r\trows/strip\n",
" -h\thorizontal sampling factor (1,2,4)\n",
" -v\tvertical sampling factor (1,2,4)\n",
NULL
};
static void
usage(int code)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(code);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,691 @@
/* $Id: thumbnail.c,v 1.21 2015-06-21 01:09:10 bfriesen Exp $ */
/*
* Copyright (c) 1994-1997 Sam Leffler
* Copyright (c) 1994-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffio.h"
#ifndef HAVE_GETOPT
extern int getopt(int, char**, char*);
#endif
#define streq(a,b) (strcmp(a,b) == 0)
#ifndef TIFFhowmany8
# define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
#endif
typedef enum {
EXP50,
EXP60,
EXP70,
EXP80,
EXP90,
EXP,
LINEAR
} Contrast;
static uint32 tnw = 216; /* thumbnail width */
static uint32 tnh = 274; /* thumbnail height */
static Contrast contrast = LINEAR; /* current contrast */
static uint8* thumbnail;
static int cpIFD(TIFF*, TIFF*);
static int generateThumbnail(TIFF*, TIFF*);
static void initScale();
static void usage(void);
#if !HAVE_DECL_OPTARG
extern char* optarg;
extern int optind;
#endif
int
main(int argc, char* argv[])
{
TIFF* in;
TIFF* out;
int c;
while ((c = getopt(argc, argv, "w:h:c:")) != -1) {
switch (c) {
case 'w': tnw = strtoul(optarg, NULL, 0); break;
case 'h': tnh = strtoul(optarg, NULL, 0); break;
case 'c': contrast = streq(optarg, "exp50") ? EXP50 :
streq(optarg, "exp60") ? EXP60 :
streq(optarg, "exp70") ? EXP70 :
streq(optarg, "exp80") ? EXP80 :
streq(optarg, "exp90") ? EXP90 :
streq(optarg, "exp") ? EXP :
streq(optarg, "linear")? LINEAR :
EXP;
break;
default: usage();
}
}
if (argc-optind != 2)
usage();
out = TIFFOpen(argv[optind+1], "w");
if (out == NULL)
return 2;
in = TIFFOpen(argv[optind], "r");
if( in == NULL )
return 2;
thumbnail = (uint8*) _TIFFmalloc(tnw * tnh);
if (!thumbnail) {
TIFFError(TIFFFileName(in),
"Can't allocate space for thumbnail buffer.");
return 1;
}
if (in != NULL) {
initScale();
do {
if (!generateThumbnail(in, out))
goto bad;
if (!cpIFD(in, out) || !TIFFWriteDirectory(out))
goto bad;
} while (TIFFReadDirectory(in));
(void) TIFFClose(in);
}
(void) TIFFClose(out);
return 0;
bad:
(void) TIFFClose(out);
return 1;
}
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
#define CopyField2(tag, v1, v2) \
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
#define CopyField3(tag, v1, v2, v3) \
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
#define CopyField4(tag, v1, v2, v3, v4) \
if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
static void
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
{
switch (type) {
case TIFF_SHORT:
if (count == 1) {
uint16 shortv;
CopyField(tag, shortv);
} else if (count == 2) {
uint16 shortv1, shortv2;
CopyField2(tag, shortv1, shortv2);
} else if (count == 4) {
uint16 *tr, *tg, *tb, *ta;
CopyField4(tag, tr, tg, tb, ta);
} else if (count == (uint16) -1) {
uint16 shortv1;
uint16* shortav;
CopyField2(tag, shortv1, shortav);
}
break;
case TIFF_LONG:
{ uint32 longv;
CopyField(tag, longv);
}
break;
case TIFF_LONG8:
{ uint64 longv8;
CopyField(tag, longv8);
}
break;
case TIFF_SLONG8:
{ int64 longv8;
CopyField(tag, longv8);
}
break;
case TIFF_RATIONAL:
if (count == 1) {
float floatv;
CopyField(tag, floatv);
} else if (count == (uint16) -1) {
float* floatav;
CopyField(tag, floatav);
}
break;
case TIFF_ASCII:
{ char* stringv;
CopyField(tag, stringv);
}
break;
case TIFF_DOUBLE:
if (count == 1) {
double doublev;
CopyField(tag, doublev);
} else if (count == (uint16) -1) {
double* doubleav;
CopyField(tag, doubleav);
}
break;
case TIFF_IFD8:
{ toff_t ifd8;
CopyField(tag, ifd8);
}
break; default:
TIFFError(TIFFFileName(in),
"Data type %d is not supported, tag %d skipped.",
tag, type);
}
}
#undef CopyField4
#undef CopyField3
#undef CopyField2
#undef CopyField
static struct cpTag {
uint16 tag;
uint16 count;
TIFFDataType type;
} tags[] = {
{ TIFFTAG_IMAGEWIDTH, 1, TIFF_LONG },
{ TIFFTAG_IMAGELENGTH, 1, TIFF_LONG },
{ TIFFTAG_BITSPERSAMPLE, 1, TIFF_SHORT },
{ TIFFTAG_COMPRESSION, 1, TIFF_SHORT },
{ TIFFTAG_FILLORDER, 1, TIFF_SHORT },
{ TIFFTAG_SAMPLESPERPIXEL, 1, TIFF_SHORT },
{ TIFFTAG_ROWSPERSTRIP, 1, TIFF_LONG },
{ TIFFTAG_PLANARCONFIG, 1, TIFF_SHORT },
{ TIFFTAG_GROUP3OPTIONS, 1, TIFF_LONG },
{ TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
{ TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT },
{ TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
{ TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
{ TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
{ TIFFTAG_MAKE, 1, TIFF_ASCII },
{ TIFFTAG_MODEL, 1, TIFF_ASCII },
{ TIFFTAG_ORIENTATION, 1, TIFF_SHORT },
{ TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
{ TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
{ TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
{ TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
{ TIFFTAG_PAGENAME, 1, TIFF_ASCII },
{ TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
{ TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
{ TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG },
{ TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
{ TIFFTAG_PAGENUMBER, 2, TIFF_SHORT },
{ TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
{ TIFFTAG_DATETIME, 1, TIFF_ASCII },
{ TIFFTAG_ARTIST, 1, TIFF_ASCII },
{ TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
{ TIFFTAG_WHITEPOINT, 2, TIFF_RATIONAL },
{ TIFFTAG_PRIMARYCHROMATICITIES, (uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
{ TIFFTAG_BADFAXLINES, 1, TIFF_LONG },
{ TIFFTAG_CLEANFAXDATA, 1, TIFF_SHORT },
{ TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG },
{ TIFFTAG_INKSET, 1, TIFF_SHORT },
/*{ TIFFTAG_INKNAMES, 1, TIFF_ASCII },*/ /* Needs much more complicated logic. See tiffcp */
{ TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
{ TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
{ TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
{ TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
{ TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
{ TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
};
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
static void
cpTags(TIFF* in, TIFF* out)
{
struct cpTag *p;
for (p = tags; p < &tags[NTAGS]; p++)
{
/* Horrible: but TIFFGetField() expects 2 arguments to be passed */
/* if we request a tag that is defined in a codec, but that codec */
/* isn't used */
if( p->tag == TIFFTAG_GROUP3OPTIONS )
{
uint16 compression;
if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) ||
compression != COMPRESSION_CCITTFAX3 )
continue;
}
if( p->tag == TIFFTAG_GROUP4OPTIONS )
{
uint16 compression;
if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) ||
compression != COMPRESSION_CCITTFAX4 )
continue;
}
cpTag(in, out, p->tag, p->count, p->type);
}
}
#undef NTAGS
static int
cpStrips(TIFF* in, TIFF* out)
{
tsize_t bufsize = TIFFStripSize(in);
unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
if (buf) {
tstrip_t s, ns = TIFFNumberOfStrips(in);
uint64 *bytecounts;
TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts);
for (s = 0; s < ns; s++) {
if (bytecounts[s] > (uint64) bufsize) {
buf = (unsigned char *)_TIFFrealloc(buf, (tmsize_t)bytecounts[s]);
if (!buf)
goto bad;
bufsize = (tmsize_t)bytecounts[s];
}
if (TIFFReadRawStrip(in, s, buf, (tmsize_t)bytecounts[s]) < 0 ||
TIFFWriteRawStrip(out, s, buf, (tmsize_t)bytecounts[s]) < 0) {
_TIFFfree(buf);
return 0;
}
}
_TIFFfree(buf);
return 1;
}
bad:
TIFFError(TIFFFileName(in),
"Can't allocate space for strip buffer.");
return 0;
}
static int
cpTiles(TIFF* in, TIFF* out)
{
tsize_t bufsize = TIFFTileSize(in);
unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
if (buf) {
ttile_t t, nt = TIFFNumberOfTiles(in);
uint64 *bytecounts;
TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts);
for (t = 0; t < nt; t++) {
if (bytecounts[t] > (uint64) bufsize) {
buf = (unsigned char *)_TIFFrealloc(buf, (tmsize_t)bytecounts[t]);
if (!buf)
goto bad;
bufsize = (tmsize_t)bytecounts[t];
}
if (TIFFReadRawTile(in, t, buf, (tmsize_t)bytecounts[t]) < 0 ||
TIFFWriteRawTile(out, t, buf, (tmsize_t)bytecounts[t]) < 0) {
_TIFFfree(buf);
return 0;
}
}
_TIFFfree(buf);
return 1;
}
bad:
TIFFError(TIFFFileName(in),
"Can't allocate space for tile buffer.");
return (0);
}
static int
cpIFD(TIFF* in, TIFF* out)
{
cpTags(in, out);
if (TIFFIsTiled(in)) {
if (!cpTiles(in, out))
return (0);
} else {
if (!cpStrips(in, out))
return (0);
}
return (1);
}
static uint16 photometric; /* current photometric of raster */
static uint16 filterWidth; /* filter width in pixels */
static uint32 stepSrcWidth; /* src image stepping width */
static uint32 stepDstWidth; /* dest stepping width */
static uint8* src0; /* horizontal bit stepping (start) */
static uint8* src1; /* horizontal bit stepping (middle) */
static uint8* src2; /* horizontal bit stepping (end) */
static uint32* rowoff; /* row offset for stepping */
static uint8 cmap[256]; /* colormap indexes */
static uint8 bits[256]; /* count of bits set */
static void
setupBitsTables()
{
int i;
for (i = 0; i < 256; i++) {
int n = 0;
if (i&0x01) n++;
if (i&0x02) n++;
if (i&0x04) n++;
if (i&0x08) n++;
if (i&0x10) n++;
if (i&0x20) n++;
if (i&0x40) n++;
if (i&0x80) n++;
bits[i] = n;
}
}
static int clamp(float v, int low, int high)
{ return (v < low ? low : v > high ? high : (int)v); }
#ifndef M_E
#define M_E 2.7182818284590452354
#endif
static void
expFill(float pct[], uint32 p, uint32 n)
{
uint32 i;
uint32 c = (p * n) / 100;
for (i = 1; i < c; i++)
pct[i] = (float) (1-exp(i/((double)(n-1)))/ M_E);
for (; i < n; i++)
pct[i] = 0.;
}
static void
setupCmap()
{
float pct[256]; /* known to be large enough */
uint32 i;
pct[0] = 1; /* force white */
switch (contrast) {
case EXP50: expFill(pct, 50, 256); break;
case EXP60: expFill(pct, 60, 256); break;
case EXP70: expFill(pct, 70, 256); break;
case EXP80: expFill(pct, 80, 256); break;
case EXP90: expFill(pct, 90, 256); break;
case EXP: expFill(pct, 100, 256); break;
case LINEAR:
for (i = 1; i < 256; i++)
pct[i] = 1-((float)i)/(256-1);
break;
}
switch (photometric) {
case PHOTOMETRIC_MINISWHITE:
for (i = 0; i < 256; i++)
cmap[i] = clamp(255*pct[(256-1)-i], 0, 255);
break;
case PHOTOMETRIC_MINISBLACK:
for (i = 0; i < 256; i++)
cmap[i] = clamp(255*pct[i], 0, 255);
break;
}
}
static void
initScale()
{
src0 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw);
src1 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw);
src2 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw);
rowoff = (uint32*) _TIFFmalloc(sizeof (uint32) * tnw);
filterWidth = 0;
stepDstWidth = stepSrcWidth = 0;
setupBitsTables();
}
/*
* Calculate the horizontal accumulation parameteres
* according to the widths of the src and dst images.
*/
static void
setupStepTables(uint32 sw)
{
if (stepSrcWidth != sw || stepDstWidth != tnw) {
int step = sw;
int limit = tnw;
int err = 0;
uint32 sx = 0;
uint32 x;
int fw;
uint8 b;
for (x = 0; x < tnw; x++) {
uint32 sx0 = sx;
err += step;
while (err >= limit) {
err -= limit;
sx++;
}
rowoff[x] = sx0 >> 3;
fw = sx - sx0; /* width */
b = (fw < 8) ? 0xff<<(8-fw) : 0xff;
src0[x] = b >> (sx0&7);
fw -= 8 - (sx0&7);
if (fw < 0)
fw = 0;
src1[x] = fw >> 3;
fw -= (fw>>3)<<3;
src2[x] = 0xff << (8-fw);
}
stepSrcWidth = sw;
stepDstWidth = tnw;
}
}
static void
setrow(uint8* row, uint32 nrows, const uint8* rows[])
{
uint32 x;
uint32 area = nrows * filterWidth;
for (x = 0; x < tnw; x++) {
uint32 mask0 = src0[x];
uint32 fw = src1[x];
uint32 mask1 = src1[x];
uint32 off = rowoff[x];
uint32 acc = 0;
uint32 y, i;
for (y = 0; y < nrows; y++) {
const uint8* src = rows[y] + off;
acc += bits[*src++ & mask0];
switch (fw) {
default:
for (i = fw; i > 8; i--)
acc += bits[*src++];
/* fall thru... */
case 8: acc += bits[*src++];
case 7: acc += bits[*src++];
case 6: acc += bits[*src++];
case 5: acc += bits[*src++];
case 4: acc += bits[*src++];
case 3: acc += bits[*src++];
case 2: acc += bits[*src++];
case 1: acc += bits[*src++];
case 0: break;
}
acc += bits[*src & mask1];
}
*row++ = cmap[(255*acc)/area];
}
}
/*
* Install the specified image. The
* image is resized to fit the display page using
* a box filter. The resultant pixels are mapped
* with a user-selectable contrast curve.
*/
static void
setImage1(const uint8* br, uint32 rw, uint32 rh)
{
int step = rh;
int limit = tnh;
int err = 0;
int bpr = TIFFhowmany8(rw);
int sy = 0;
uint8* row = thumbnail;
uint32 dy;
for (dy = 0; dy < tnh; dy++) {
const uint8* rows[256];
uint32 nrows = 1;
fprintf(stderr, "bpr=%d, sy=%d, bpr*sy=%d\n", bpr, sy, bpr*sy);
rows[0] = br + bpr*sy;
err += step;
while (err >= limit) {
err -= limit;
sy++;
if (err >= limit)
{
/* We should perhaps error loudly, but I can't make sense of that */
/* code... */
if( nrows == 256 )
break;
rows[nrows++] = br + bpr*sy;
}
}
setrow(row, nrows, rows);
row += tnw;
}
}
static void
setImage(const uint8* br, uint32 rw, uint32 rh)
{
filterWidth = (uint16) ceil((double) rw / (double) tnw);
setupStepTables(rw);
setImage1(br, rw, rh);
}
static int
generateThumbnail(TIFF* in, TIFF* out)
{
unsigned char* raster;
unsigned char* rp;
uint32 sw, sh, rps;
uint16 bps, spp;
tsize_t rowsize, rastersize;
tstrip_t s, ns = TIFFNumberOfStrips(in);
toff_t diroff[1];
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &sw);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &sh);
TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
if (spp != 1 || bps != 1)
return 0;
rowsize = TIFFScanlineSize(in);
rastersize = sh * rowsize;
fprintf(stderr, "rastersize=%u\n", (unsigned int)rastersize);
/* +3 : add a few guard bytes since setrow() can read a bit */
/* outside buffer */
raster = (unsigned char*)_TIFFmalloc(rastersize+3);
if (!raster) {
TIFFError(TIFFFileName(in),
"Can't allocate space for raster buffer.");
return 0;
}
raster[rastersize] = 0;
raster[rastersize+1] = 0;
raster[rastersize+2] = 0;
rp = raster;
for (s = 0; s < ns; s++) {
(void) TIFFReadEncodedStrip(in, s, rp, -1);
rp += rps * rowsize;
}
TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric);
setupCmap();
setImage(raster, sw, sh);
_TIFFfree(raster);
TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) tnw);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) tnh);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, (uint16) 8);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, (uint16) 1);
TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
cpTag(in, out, TIFFTAG_SOFTWARE, (uint16) -1, TIFF_ASCII);
cpTag(in, out, TIFFTAG_IMAGEDESCRIPTION, (uint16) -1, TIFF_ASCII);
cpTag(in, out, TIFFTAG_DATETIME, (uint16) -1, TIFF_ASCII);
cpTag(in, out, TIFFTAG_HOSTCOMPUTER, (uint16) -1, TIFF_ASCII);
diroff[0] = 0UL;
TIFFSetField(out, TIFFTAG_SUBIFD, 1, diroff);
return (TIFFWriteEncodedStrip(out, 0, thumbnail, tnw*tnh) != -1 &&
TIFFWriteDirectory(out) != -1);
}
char* stuff[] = {
"usage: thumbnail [options] input.tif output.tif",
"where options are:",
" -h # specify thumbnail image height (default is 274)",
" -w # specify thumbnail image width (default is 216)",
"",
" -c linear use linear contrast curve",
" -c exp50 use 50% exponential contrast curve",
" -c exp60 use 60% exponential contrast curve",
" -c exp70 use 70% exponential contrast curve",
" -c exp80 use 80% exponential contrast curve",
" -c exp90 use 90% exponential contrast curve",
" -c exp use pure exponential contrast curve",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,517 @@
/* $Id: tiff2bw.c,v 1.21 2017-11-01 13:41:58 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffio.h"
#define streq(a,b) (strcmp((a),(b)) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
/* x% weighting -> fraction of full color */
#define PCT(x) (((x)*256+50)/100)
int RED = PCT(30); /* 30% */
int GREEN = PCT(59); /* 59% */
int BLUE = PCT(11); /* 11% */
static void usage(void);
static int processCompressOptions(char*);
static void
compresscontig(unsigned char* out, unsigned char* rgb, uint32 n)
{
register int v, red = RED, green = GREEN, blue = BLUE;
while (n-- > 0) {
v = red*(*rgb++);
v += green*(*rgb++);
v += blue*(*rgb++);
*out++ = v>>8;
}
}
static void
compresssep(unsigned char* out,
unsigned char* r, unsigned char* g, unsigned char* b, uint32 n)
{
register uint32 red = RED, green = GREEN, blue = BLUE;
while (n-- > 0)
*out++ = (unsigned char)
((red*(*r++) + green*(*g++) + blue*(*b++)) >> 8);
}
static int
checkcmap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b)
{
while (n-- > 0)
if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
return (16);
TIFFWarning(TIFFFileName(tif), "Assuming 8-bit colormap");
return (8);
}
static void
compresspalette(unsigned char* out, unsigned char* data, uint32 n, uint16* rmap, uint16* gmap, uint16* bmap)
{
register int v, red = RED, green = GREEN, blue = BLUE;
while (n-- > 0) {
unsigned int ix = *data++;
v = red*rmap[ix];
v += green*gmap[ix];
v += blue*bmap[ix];
*out++ = v>>8;
}
}
static uint16 compression = (uint16) -1;
static uint16 predictor = 0;
static int jpegcolormode = JPEGCOLORMODE_RGB;
static int quality = 75; /* JPEG quality */
static void cpTags(TIFF* in, TIFF* out);
int
main(int argc, char* argv[])
{
uint32 rowsperstrip = (uint32) -1;
TIFF *in, *out;
uint32 w, h;
uint16 samplesperpixel;
uint16 bitspersample;
uint16 config;
uint16 photometric;
uint16* red;
uint16* green;
uint16* blue;
tsize_t rowsize;
register uint32 row;
register tsample_t s;
unsigned char *inbuf, *outbuf;
char thing[1024];
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char *optarg;
#endif
in = (TIFF *) NULL;
out = (TIFF *) NULL;
inbuf = (unsigned char *) NULL;
outbuf = (unsigned char *) NULL;
while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1)
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case 'R':
RED = PCT(atoi(optarg));
break;
case 'G':
GREEN = PCT(atoi(optarg));
break;
case 'B':
BLUE = PCT(atoi(optarg));
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind < 2)
usage();
in = TIFFOpen(argv[optind], "r");
if (in == NULL)
return (-1);
photometric = 0;
TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric);
if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE ) {
fprintf(stderr,
"%s: Bad photometric; can only handle RGB and Palette images.\n",
argv[optind]);
goto tiff2bw_error;
}
TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
if (samplesperpixel != 1 && samplesperpixel != 3) {
fprintf(stderr, "%s: Bad samples/pixel %u.\n",
argv[optind], samplesperpixel);
goto tiff2bw_error;
}
if( photometric == PHOTOMETRIC_RGB && samplesperpixel != 3) {
fprintf(stderr, "%s: Bad samples/pixel %u for PHOTOMETRIC_RGB.\n",
argv[optind], samplesperpixel);
goto tiff2bw_error;
}
TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
if (bitspersample != 8) {
fprintf(stderr,
" %s: Sorry, only handle 8-bit samples.\n", argv[optind]);
goto tiff2bw_error;
}
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config);
out = TIFFOpen(argv[optind+1], "w");
if (out == NULL)
{
goto tiff2bw_error;
}
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, w);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, h);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
cpTags(in, out);
if (compression != (uint16) -1) {
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
switch (compression) {
case COMPRESSION_JPEG:
TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
break;
case COMPRESSION_LZW:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
}
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
snprintf(thing, sizeof(thing), "B&W version of %s", argv[optind]);
TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw");
outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
#define pack(a,b) ((a)<<8 | (b))
switch (pack(photometric, config)) {
case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG):
case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE):
TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue);
/*
* Convert 16-bit colormap to 8-bit (unless it looks
* like an old-style 8-bit colormap).
*/
if (checkcmap(in, 1<<bitspersample, red, green, blue) == 16) {
int i;
#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
for (i = (1<<bitspersample)-1; i >= 0; i--) {
red[i] = CVT(red[i]);
green[i] = CVT(green[i]);
blue[i] = CVT(blue[i]);
}
#undef CVT
}
inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
for (row = 0; row < h; row++) {
if (TIFFReadScanline(in, inbuf, row, 0) < 0)
break;
compresspalette(outbuf, inbuf, w, red, green, blue);
if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
break;
}
break;
case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG):
inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
for (row = 0; row < h; row++) {
if (TIFFReadScanline(in, inbuf, row, 0) < 0)
break;
compresscontig(outbuf, inbuf, w);
if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
break;
}
break;
case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE):
rowsize = TIFFScanlineSize(in);
inbuf = (unsigned char *)_TIFFmalloc(3*rowsize);
for (row = 0; row < h; row++) {
for (s = 0; s < 3; s++)
if (TIFFReadScanline(in,
inbuf+s*rowsize, row, s) < 0)
goto tiff2bw_error;
compresssep(outbuf,
inbuf, inbuf+rowsize, inbuf+2*rowsize, w);
if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
break;
}
break;
}
#undef pack
if (inbuf)
_TIFFfree(inbuf);
if (outbuf)
_TIFFfree(outbuf);
TIFFClose(in);
TIFFClose(out);
return (0);
tiff2bw_error:
if (inbuf)
_TIFFfree(inbuf);
if (outbuf)
_TIFFfree(outbuf);
if (out)
TIFFClose(out);
if (in)
TIFFClose(in);
return (-1);
}
static int
processCompressOptions(char* opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "jpeg", 4)) {
char* cp = strchr(opt, ':');
compression = COMPRESSION_JPEG;
while( cp )
{
if (isdigit((int)cp[1]))
quality = atoi(cp+1);
else if (cp[1] == 'r' )
jpegcolormode = JPEGCOLORMODE_RAW;
else
usage();
cp = strchr(cp+1,':');
}
} else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_DEFLATE;
} else
return (0);
return (1);
}
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
#define CopyField2(tag, v1, v2) \
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
#define CopyField3(tag, v1, v2, v3) \
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
#define CopyField4(tag, v1, v2, v3, v4) \
if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)
static void
cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type)
{
switch (type) {
case TIFF_SHORT:
if (count == 1) {
uint16 shortv;
CopyField(tag, shortv);
} else if (count == 2) {
uint16 shortv1, shortv2;
CopyField2(tag, shortv1, shortv2);
} else if (count == 4) {
uint16 *tr, *tg, *tb, *ta;
CopyField4(tag, tr, tg, tb, ta);
} else if (count == (uint16) -1) {
uint16 shortv1;
uint16* shortav;
CopyField2(tag, shortv1, shortav);
}
break;
case TIFF_LONG:
{ uint32 longv;
CopyField(tag, longv);
}
break;
case TIFF_RATIONAL:
if (count == 1) {
float floatv;
CopyField(tag, floatv);
} else if (count == (uint16) -1) {
float* floatav;
CopyField(tag, floatav);
}
break;
case TIFF_ASCII:
{ char* stringv;
CopyField(tag, stringv);
}
break;
case TIFF_DOUBLE:
if (count == 1) {
double doublev;
CopyField(tag, doublev);
} else if (count == (uint16) -1) {
double* doubleav;
CopyField(tag, doubleav);
}
break;
default:
TIFFError(TIFFFileName(in),
"Data type %d is not supported, tag %d skipped.",
tag, type);
}
}
#undef CopyField4
#undef CopyField3
#undef CopyField2
#undef CopyField
static struct cpTag {
uint16 tag;
uint16 count;
TIFFDataType type;
} tags[] = {
{ TIFFTAG_SUBFILETYPE, 1, TIFF_LONG },
{ TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT },
{ TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII },
{ TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII },
{ TIFFTAG_MAKE, 1, TIFF_ASCII },
{ TIFFTAG_MODEL, 1, TIFF_ASCII },
{ TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT },
{ TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT },
{ TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL },
{ TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL },
{ TIFFTAG_PAGENAME, 1, TIFF_ASCII },
{ TIFFTAG_XPOSITION, 1, TIFF_RATIONAL },
{ TIFFTAG_YPOSITION, 1, TIFF_RATIONAL },
{ TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT },
{ TIFFTAG_SOFTWARE, 1, TIFF_ASCII },
{ TIFFTAG_DATETIME, 1, TIFF_ASCII },
{ TIFFTAG_ARTIST, 1, TIFF_ASCII },
{ TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII },
{ TIFFTAG_WHITEPOINT, 2, TIFF_RATIONAL },
{ TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT },
{ TIFFTAG_INKSET, 1, TIFF_SHORT },
{ TIFFTAG_DOTRANGE, 2, TIFF_SHORT },
{ TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII },
{ TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT },
{ TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT },
{ TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT },
{ TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL },
{ TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },
{ TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
{ TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
{ TIFFTAG_STONITS, 1, TIFF_DOUBLE },
};
#define NTAGS (sizeof (tags) / sizeof (tags[0]))
static void
cpTags(TIFF* in, TIFF* out)
{
struct cpTag *p;
for (p = tags; p < &tags[NTAGS]; p++)
{
if( p->tag == TIFFTAG_GROUP3OPTIONS )
{
uint16 compression;
if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) ||
compression != COMPRESSION_CCITTFAX3 )
continue;
}
if( p->tag == TIFFTAG_GROUP4OPTIONS )
{
uint16 compression;
if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) ||
compression != COMPRESSION_CCITTFAX4 )
continue;
}
cpTag(in, out, p->tag, p->count, p->type);
}
}
#undef NTAGS
char* stuff[] = {
"usage: tiff2bw [options] input.tif output.tif",
"where options are:",
" -R % use #% from red channel",
" -G % use #% from green channel",
" -B % use #% from blue channel",
"",
" -r # make each strip have no more than # rows",
"",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c packbits compress output with packbits encoding",
" -c g3[:opts] compress output with CCITT Group 3 encoding",
" -c g4 compress output with CCITT Group 4 encoding",
" -c none use no compression algorithm on output",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,569 @@
/* $Id: tiff2rgba.c,v 1.22 2016-08-15 20:06:41 erouault Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffiop.h"
#include "tiffio.h"
#define streq(a,b) (strcmp(a,b) == 0)
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
#define roundup(x, y) (howmany(x,y)*((uint32)(y)))
uint16 compression = COMPRESSION_PACKBITS;
uint32 rowsperstrip = (uint32) -1;
int process_by_block = 0; /* default is whole image at once */
int no_alpha = 0;
int bigtiff_output = 0;
static int tiffcvt(TIFF* in, TIFF* out);
static void usage(int code);
int
main(int argc, char* argv[])
{
TIFF *in, *out;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char *optarg;
#endif
while ((c = getopt(argc, argv, "c:r:t:bn8")) != -1)
switch (c) {
case 'b':
process_by_block = 1;
break;
case 'c':
if (streq(optarg, "none"))
compression = COMPRESSION_NONE;
else if (streq(optarg, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (streq(optarg, "lzw"))
compression = COMPRESSION_LZW;
else if (streq(optarg, "jpeg"))
compression = COMPRESSION_JPEG;
else if (streq(optarg, "zip"))
compression = COMPRESSION_DEFLATE;
else
usage(-1);
break;
case 'r':
rowsperstrip = atoi(optarg);
break;
case 't':
rowsperstrip = atoi(optarg);
break;
case 'n':
no_alpha = 1;
break;
case '8':
bigtiff_output = 1;
break;
case '?':
usage(0);
/*NOTREACHED*/
}
if (argc - optind < 2)
usage(-1);
out = TIFFOpen(argv[argc-1], bigtiff_output?"w8":"w");
if (out == NULL)
return (-2);
for (; optind < argc-1; optind++) {
in = TIFFOpen(argv[optind], "r");
if (in != NULL) {
do {
if (!tiffcvt(in, out) ||
!TIFFWriteDirectory(out)) {
(void) TIFFClose(out);
(void) TIFFClose(in);
return (1);
}
} while (TIFFReadDirectory(in));
(void) TIFFClose(in);
}
}
(void) TIFFClose(out);
return (0);
}
static int
cvt_by_tile( TIFF *in, TIFF *out )
{
uint32* raster; /* retrieve RGBA image */
uint32 width, height; /* image width & height */
uint32 tile_width, tile_height;
uint32 row, col;
uint32 *wrk_line;
int ok = 1;
uint32 rastersize, wrk_linesize;
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
if( !TIFFGetField(in, TIFFTAG_TILEWIDTH, &tile_width)
|| !TIFFGetField(in, TIFFTAG_TILELENGTH, &tile_height) ) {
TIFFError(TIFFFileName(in), "Source image not tiled");
return (0);
}
TIFFSetField(out, TIFFTAG_TILEWIDTH, tile_width );
TIFFSetField(out, TIFFTAG_TILELENGTH, tile_height );
/*
* Allocate tile buffer
*/
rastersize = tile_width * tile_height * sizeof (uint32);
if (tile_width != (rastersize / tile_height) / sizeof( uint32))
{
TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer");
exit(-1);
}
raster = (uint32*)_TIFFmalloc(rastersize);
if (raster == 0) {
TIFFError(TIFFFileName(in), "No space for raster buffer");
return (0);
}
/*
* Allocate a scanline buffer for swapping during the vertical
* mirroring pass.
*/
wrk_linesize = tile_width * sizeof (uint32);
if (tile_width != wrk_linesize / sizeof (uint32))
{
TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer");
exit(-1);
}
wrk_line = (uint32*)_TIFFmalloc(wrk_linesize);
if (!wrk_line) {
TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
ok = 0;
}
/*
* Loop over the tiles.
*/
for( row = 0; ok && row < height; row += tile_height )
{
for( col = 0; ok && col < width; col += tile_width )
{
uint32 i_row;
/* Read the tile into an RGBA array */
if (!TIFFReadRGBATile(in, col, row, raster)) {
ok = 0;
break;
}
/*
* XXX: raster array has 4-byte unsigned integer type, that is why
* we should rearrange it here.
*/
#if HOST_BIGENDIAN
TIFFSwabArrayOfLong(raster, tile_width * tile_height);
#endif
/*
* For some reason the TIFFReadRGBATile() function chooses the
* lower left corner as the origin. Vertically mirror scanlines.
*/
for( i_row = 0; i_row < tile_height / 2; i_row++ )
{
uint32 *top_line, *bottom_line;
top_line = raster + tile_width * i_row;
bottom_line = raster + tile_width * (tile_height-i_row-1);
_TIFFmemcpy(wrk_line, top_line, 4*tile_width);
_TIFFmemcpy(top_line, bottom_line, 4*tile_width);
_TIFFmemcpy(bottom_line, wrk_line, 4*tile_width);
}
/*
* Write out the result in a tile.
*/
if( TIFFWriteEncodedTile( out,
TIFFComputeTile( out, col, row, 0, 0),
raster,
4 * tile_width * tile_height ) == -1 )
{
ok = 0;
break;
}
}
}
_TIFFfree( raster );
_TIFFfree( wrk_line );
return ok;
}
static int
cvt_by_strip( TIFF *in, TIFF *out )
{
uint32* raster; /* retrieve RGBA image */
uint32 width, height; /* image width & height */
uint32 row;
uint32 *wrk_line;
int ok = 1;
uint32 rastersize, wrk_linesize;
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
if( !TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip) ) {
TIFFError(TIFFFileName(in), "Source image not in strips");
return (0);
}
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
/*
* Allocate strip buffer
*/
rastersize = width * rowsperstrip * sizeof (uint32);
if (width != (rastersize / rowsperstrip) / sizeof( uint32))
{
TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer");
exit(-1);
}
raster = (uint32*)_TIFFmalloc(rastersize);
if (raster == 0) {
TIFFError(TIFFFileName(in), "No space for raster buffer");
return (0);
}
/*
* Allocate a scanline buffer for swapping during the vertical
* mirroring pass.
*/
wrk_linesize = width * sizeof (uint32);
if (width != wrk_linesize / sizeof (uint32))
{
TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer");
exit(-1);
}
wrk_line = (uint32*)_TIFFmalloc(wrk_linesize);
if (!wrk_line) {
TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
ok = 0;
}
/*
* Loop over the strips.
*/
for( row = 0; ok && row < height; row += rowsperstrip )
{
int rows_to_write, i_row;
/* Read the strip into an RGBA array */
if (!TIFFReadRGBAStrip(in, row, raster)) {
ok = 0;
break;
}
/*
* XXX: raster array has 4-byte unsigned integer type, that is why
* we should rearrange it here.
*/
#if HOST_BIGENDIAN
TIFFSwabArrayOfLong(raster, width * rowsperstrip);
#endif
/*
* Figure out the number of scanlines actually in this strip.
*/
if( row + rowsperstrip > height )
rows_to_write = height - row;
else
rows_to_write = rowsperstrip;
/*
* For some reason the TIFFReadRGBAStrip() function chooses the
* lower left corner as the origin. Vertically mirror scanlines.
*/
for( i_row = 0; i_row < rows_to_write / 2; i_row++ )
{
uint32 *top_line, *bottom_line;
top_line = raster + width * i_row;
bottom_line = raster + width * (rows_to_write-i_row-1);
_TIFFmemcpy(wrk_line, top_line, 4*width);
_TIFFmemcpy(top_line, bottom_line, 4*width);
_TIFFmemcpy(bottom_line, wrk_line, 4*width);
}
/*
* Write out the result in a strip
*/
if( TIFFWriteEncodedStrip( out, row / rowsperstrip, raster,
4 * rows_to_write * width ) == -1 )
{
ok = 0;
break;
}
}
_TIFFfree( raster );
_TIFFfree( wrk_line );
return ok;
}
/*
* cvt_whole_image()
*
* read the whole image into one big RGBA buffer and then write out
* strips from that. This is using the traditional TIFFReadRGBAImage()
* API that we trust.
*/
static int
cvt_whole_image( TIFF *in, TIFF *out )
{
uint32* raster; /* retrieve RGBA image */
uint32 width, height; /* image width & height */
uint32 row;
size_t pixel_count;
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
pixel_count = width * height;
/* XXX: Check the integer overflow. */
if (!width || !height || pixel_count / width != height) {
TIFFError(TIFFFileName(in),
"Malformed input file; can't allocate buffer for raster of %lux%lu size",
(unsigned long)width, (unsigned long)height);
return 0;
}
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
raster = (uint32*)_TIFFCheckMalloc(in, pixel_count, sizeof(uint32), "raster buffer");
if (raster == 0) {
TIFFError(TIFFFileName(in), "Failed to allocate buffer (%lu elements of %lu each)",
(unsigned long)pixel_count, (unsigned long)sizeof(uint32));
return (0);
}
/* Read the image in one chunk into an RGBA array */
if (!TIFFReadRGBAImageOriented(in, width, height, raster,
ORIENTATION_TOPLEFT, 0)) {
_TIFFfree(raster);
return (0);
}
/*
* XXX: raster array has 4-byte unsigned integer type, that is why
* we should rearrange it here.
*/
#if HOST_BIGENDIAN
TIFFSwabArrayOfLong(raster, width * height);
#endif
/*
* Do we want to strip away alpha components?
*/
if (no_alpha)
{
size_t count = pixel_count;
unsigned char *src, *dst;
src = dst = (unsigned char *) raster;
while (count > 0)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
src++;
count--;
}
}
/*
* Write out the result in strips
*/
for (row = 0; row < height; row += rowsperstrip)
{
unsigned char * raster_strip;
int rows_to_write;
int bytes_per_pixel;
if (no_alpha)
{
raster_strip = ((unsigned char *) raster) + 3 * row * width;
bytes_per_pixel = 3;
}
else
{
raster_strip = (unsigned char *) (raster + row * width);
bytes_per_pixel = 4;
}
if( row + rowsperstrip > height )
rows_to_write = height - row;
else
rows_to_write = rowsperstrip;
if( TIFFWriteEncodedStrip( out, row / rowsperstrip, raster_strip,
bytes_per_pixel * rows_to_write * width ) == -1 )
{
_TIFFfree( raster );
return 0;
}
}
_TIFFfree( raster );
return 1;
}
static int
tiffcvt(TIFF* in, TIFF* out)
{
uint32 width, height; /* image width & height */
uint16 shortv;
float floatv;
char *stringv;
uint32 longv;
uint16 v[1];
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
CopyField(TIFFTAG_SUBFILETYPE, longv);
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
CopyField(TIFFTAG_FILLORDER, shortv);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
if( no_alpha )
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
else
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 4);
if( !no_alpha )
{
v[0] = EXTRASAMPLE_ASSOCALPHA;
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, v);
}
CopyField(TIFFTAG_XRESOLUTION, floatv);
CopyField(TIFFTAG_YRESOLUTION, floatv);
CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion());
CopyField(TIFFTAG_DOCUMENTNAME, stringv);
if( process_by_block && TIFFIsTiled( in ) )
return( cvt_by_tile( in, out ) );
else if( process_by_block )
return( cvt_by_strip( in, out ) );
else
return( cvt_whole_image( in, out ) );
}
static char* stuff[] = {
"usage: tiff2rgba [-c comp] [-r rows] [-b] [-n] [-8] input... output",
"where comp is one of the following compression algorithms:",
" jpeg\t\tJPEG encoding",
" zip\t\tZip/Deflate encoding",
" lzw\t\tLempel-Ziv & Welch encoding",
" packbits\tPackBits encoding",
" none\t\tno compression",
"and the other options are:",
" -r\trows/strip",
" -b (progress by block rather than as a whole image)",
" -n don't emit alpha component.",
" -8 write BigTIFF file instead of ClassicTIFF",
NULL
};
static void
usage(int code)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(code);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,659 @@
/* $Id: tiffcmp.c,v 1.18 2015-06-21 01:09:10 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffio.h"
#ifndef HAVE_GETOPT
extern int getopt(int, char**, char*);
#endif
static int stopondiff = 1;
static int stoponfirsttag = 1;
static uint16 bitspersample = 1;
static uint16 samplesperpixel = 1;
static uint16 sampleformat = SAMPLEFORMAT_UINT;
static uint32 imagewidth;
static uint32 imagelength;
static void usage(void);
static int tiffcmp(TIFF*, TIFF*);
static int cmptags(TIFF*, TIFF*);
static int ContigCompare(int, uint32, unsigned char*, unsigned char*, tsize_t);
static int SeparateCompare(int, int, uint32, unsigned char*, unsigned char*);
static void PrintIntDiff(uint32, int, uint32, uint32, uint32);
static void PrintFloatDiff(uint32, int, uint32, double, double);
static void leof(const char*, uint32, int);
int
main(int argc, char* argv[])
{
TIFF *tif1, *tif2;
int c, dirnum;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
while ((c = getopt(argc, argv, "ltz:")) != -1)
switch (c) {
case 'l':
stopondiff = 0;
break;
case 'z':
stopondiff = atoi(optarg);
break;
case 't':
stoponfirsttag = 0;
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind < 2)
usage();
tif1 = TIFFOpen(argv[optind], "r");
if (tif1 == NULL)
return (-1);
tif2 = TIFFOpen(argv[optind+1], "r");
if (tif2 == NULL)
return (-2);
dirnum = 0;
while (tiffcmp(tif1, tif2)) {
if (!TIFFReadDirectory(tif1)) {
if (!TIFFReadDirectory(tif2))
break;
printf("No more directories for %s\n",
TIFFFileName(tif1));
return (1);
} else if (!TIFFReadDirectory(tif2)) {
printf("No more directories for %s\n",
TIFFFileName(tif2));
return (1);
}
printf("Directory %d:\n", ++dirnum);
}
TIFFClose(tif1);
TIFFClose(tif2);
return (0);
}
char* stuff[] = {
"usage: tiffcmp [options] file1 file2",
"where options are:",
" -l list each byte of image data that differs between the files",
" -z # list specified number of bytes that differs between the files",
" -t ignore any differences in directory tags",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
#define checkEOF(tif, row, sample) { \
leof(TIFFFileName(tif), row, sample); \
goto bad; \
}
static int CheckShortTag(TIFF*, TIFF*, int, char*);
static int CheckShort2Tag(TIFF*, TIFF*, int, char*);
static int CheckShortArrayTag(TIFF*, TIFF*, int, char*);
static int CheckLongTag(TIFF*, TIFF*, int, char*);
static int CheckFloatTag(TIFF*, TIFF*, int, char*);
static int CheckStringTag(TIFF*, TIFF*, int, char*);
static int
tiffcmp(TIFF* tif1, TIFF* tif2)
{
uint16 config1, config2;
tsize_t size1;
uint32 row;
tsample_t s;
unsigned char *buf1, *buf2;
if (!CheckShortTag(tif1, tif2, TIFFTAG_BITSPERSAMPLE, "BitsPerSample"))
return (0);
if (!CheckShortTag(tif1, tif2, TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel"))
return (0);
if (!CheckLongTag(tif1, tif2, TIFFTAG_IMAGEWIDTH, "ImageWidth"))
return (0);
if (!cmptags(tif1, tif2))
return (1);
(void) TIFFGetField(tif1, TIFFTAG_BITSPERSAMPLE, &bitspersample);
(void) TIFFGetField(tif1, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
(void) TIFFGetField(tif1, TIFFTAG_SAMPLEFORMAT, &sampleformat);
(void) TIFFGetField(tif1, TIFFTAG_IMAGEWIDTH, &imagewidth);
(void) TIFFGetField(tif1, TIFFTAG_IMAGELENGTH, &imagelength);
(void) TIFFGetField(tif1, TIFFTAG_PLANARCONFIG, &config1);
(void) TIFFGetField(tif2, TIFFTAG_PLANARCONFIG, &config2);
buf1 = (unsigned char *)_TIFFmalloc(size1 = TIFFScanlineSize(tif1));
buf2 = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif2));
if (buf1 == NULL || buf2 == NULL) {
fprintf(stderr, "No space for scanline buffers\n");
exit(-1);
}
if (config1 != config2 && bitspersample != 8 && samplesperpixel > 1) {
fprintf(stderr,
"Can't handle different planar configuration w/ different bits/sample\n");
goto bad;
}
#define pack(a,b) ((a)<<8)|(b)
switch (pack(config1, config2)) {
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG):
for (row = 0; row < imagelength; row++) {
if (TIFFReadScanline(tif2, buf2, row, 0) < 0)
checkEOF(tif2, row, -1)
for (s = 0; s < samplesperpixel; s++) {
if (TIFFReadScanline(tif1, buf1, row, s) < 0)
checkEOF(tif1, row, s)
if (SeparateCompare(1, s, row, buf2, buf1) < 0)
goto bad1;
}
}
break;
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE):
for (row = 0; row < imagelength; row++) {
if (TIFFReadScanline(tif1, buf1, row, 0) < 0)
checkEOF(tif1, row, -1)
for (s = 0; s < samplesperpixel; s++) {
if (TIFFReadScanline(tif2, buf2, row, s) < 0)
checkEOF(tif2, row, s)
if (SeparateCompare(0, s, row, buf1, buf2) < 0)
goto bad1;
}
}
break;
case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE):
for (s = 0; s < samplesperpixel; s++)
for (row = 0; row < imagelength; row++) {
if (TIFFReadScanline(tif1, buf1, row, s) < 0)
checkEOF(tif1, row, s)
if (TIFFReadScanline(tif2, buf2, row, s) < 0)
checkEOF(tif2, row, s)
if (ContigCompare(s, row, buf1, buf2, size1) < 0)
goto bad1;
}
break;
case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG):
for (row = 0; row < imagelength; row++) {
if (TIFFReadScanline(tif1, buf1, row, 0) < 0)
checkEOF(tif1, row, -1)
if (TIFFReadScanline(tif2, buf2, row, 0) < 0)
checkEOF(tif2, row, -1)
if (ContigCompare(-1, row, buf1, buf2, size1) < 0)
goto bad1;
}
break;
}
if (buf1) _TIFFfree(buf1);
if (buf2) _TIFFfree(buf2);
return (1);
bad:
if (stopondiff)
exit(1);
bad1:
if (buf1) _TIFFfree(buf1);
if (buf2) _TIFFfree(buf2);
return (0);
}
#define CmpShortField(tag, name) \
if (!CheckShortTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
#define CmpShortField2(tag, name) \
if (!CheckShort2Tag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
#define CmpLongField(tag, name) \
if (!CheckLongTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
#define CmpFloatField(tag, name) \
if (!CheckFloatTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
#define CmpStringField(tag, name) \
if (!CheckStringTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
#define CmpShortArrayField(tag, name) \
if (!CheckShortArrayTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
static int
cmptags(TIFF* tif1, TIFF* tif2)
{
uint16 compression1, compression2;
CmpLongField(TIFFTAG_SUBFILETYPE, "SubFileType");
CmpLongField(TIFFTAG_IMAGEWIDTH, "ImageWidth");
CmpLongField(TIFFTAG_IMAGELENGTH, "ImageLength");
CmpShortField(TIFFTAG_BITSPERSAMPLE, "BitsPerSample");
CmpShortField(TIFFTAG_COMPRESSION, "Compression");
CmpShortField(TIFFTAG_PREDICTOR, "Predictor");
CmpShortField(TIFFTAG_PHOTOMETRIC, "PhotometricInterpretation");
CmpShortField(TIFFTAG_THRESHHOLDING, "Thresholding");
CmpShortField(TIFFTAG_FILLORDER, "FillOrder");
CmpShortField(TIFFTAG_ORIENTATION, "Orientation");
CmpShortField(TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel");
CmpShortField(TIFFTAG_MINSAMPLEVALUE, "MinSampleValue");
CmpShortField(TIFFTAG_MAXSAMPLEVALUE, "MaxSampleValue");
CmpShortField(TIFFTAG_SAMPLEFORMAT, "SampleFormat");
CmpFloatField(TIFFTAG_XRESOLUTION, "XResolution");
CmpFloatField(TIFFTAG_YRESOLUTION, "YResolution");
if( TIFFGetField(tif1, TIFFTAG_COMPRESSION, &compression1) &&
compression1 == COMPRESSION_CCITTFAX3 &&
TIFFGetField(tif2, TIFFTAG_COMPRESSION, &compression2) &&
compression2 == COMPRESSION_CCITTFAX3 )
{
CmpLongField(TIFFTAG_GROUP3OPTIONS, "Group3Options");
}
if( TIFFGetField(tif1, TIFFTAG_COMPRESSION, &compression1) &&
compression1 == COMPRESSION_CCITTFAX4 &&
TIFFGetField(tif2, TIFFTAG_COMPRESSION, &compression2) &&
compression2 == COMPRESSION_CCITTFAX4 )
{
CmpLongField(TIFFTAG_GROUP4OPTIONS, "Group4Options");
}
CmpShortField(TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit");
CmpShortField(TIFFTAG_PLANARCONFIG, "PlanarConfiguration");
CmpLongField(TIFFTAG_ROWSPERSTRIP, "RowsPerStrip");
CmpFloatField(TIFFTAG_XPOSITION, "XPosition");
CmpFloatField(TIFFTAG_YPOSITION, "YPosition");
CmpShortField(TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit");
CmpShortField(TIFFTAG_COLORRESPONSEUNIT, "ColorResponseUnit");
#ifdef notdef
{ uint16 *graycurve;
CmpField(TIFFTAG_GRAYRESPONSECURVE, graycurve);
}
{ uint16 *red, *green, *blue;
CmpField3(TIFFTAG_COLORRESPONSECURVE, red, green, blue);
}
{ uint16 *red, *green, *blue;
CmpField3(TIFFTAG_COLORMAP, red, green, blue);
}
#endif
CmpShortField2(TIFFTAG_PAGENUMBER, "PageNumber");
CmpStringField(TIFFTAG_ARTIST, "Artist");
CmpStringField(TIFFTAG_IMAGEDESCRIPTION,"ImageDescription");
CmpStringField(TIFFTAG_MAKE, "Make");
CmpStringField(TIFFTAG_MODEL, "Model");
CmpStringField(TIFFTAG_SOFTWARE, "Software");
CmpStringField(TIFFTAG_DATETIME, "DateTime");
CmpStringField(TIFFTAG_HOSTCOMPUTER, "HostComputer");
CmpStringField(TIFFTAG_PAGENAME, "PageName");
CmpStringField(TIFFTAG_DOCUMENTNAME, "DocumentName");
CmpShortField(TIFFTAG_MATTEING, "Matteing");
CmpShortArrayField(TIFFTAG_EXTRASAMPLES,"ExtraSamples");
return (1);
}
static int
ContigCompare(int sample, uint32 row,
unsigned char* p1, unsigned char* p2, tsize_t size)
{
uint32 pix;
int ppb = 8 / bitspersample;
int samples_to_test;
if (memcmp(p1, p2, size) == 0)
return 0;
samples_to_test = (sample == -1) ? samplesperpixel : 1;
switch (bitspersample) {
case 1: case 2: case 4: case 8:
{
unsigned char *pix1 = p1, *pix2 = p2;
for (pix = 0; pix < imagewidth; pix += ppb) {
int s;
for(s = 0; s < samples_to_test; s++) {
if (*pix1 != *pix2) {
if( sample == -1 )
PrintIntDiff(row, s, pix, *pix1, *pix2);
else
PrintIntDiff(row, sample, pix, *pix1, *pix2);
}
pix1++;
pix2++;
}
}
break;
}
case 16:
{
uint16 *pix1 = (uint16 *)p1, *pix2 = (uint16 *)p2;
for (pix = 0; pix < imagewidth; pix++) {
int s;
for(s = 0; s < samples_to_test; s++) {
if (*pix1 != *pix2)
PrintIntDiff(row, sample, pix, *pix1, *pix2);
pix1++;
pix2++;
}
}
break;
}
case 32:
if (sampleformat == SAMPLEFORMAT_UINT
|| sampleformat == SAMPLEFORMAT_INT) {
uint32 *pix1 = (uint32 *)p1, *pix2 = (uint32 *)p2;
for (pix = 0; pix < imagewidth; pix++) {
int s;
for(s = 0; s < samples_to_test; s++) {
if (*pix1 != *pix2) {
PrintIntDiff(row, sample, pix,
*pix1, *pix2);
}
pix1++;
pix2++;
}
}
} else if (sampleformat == SAMPLEFORMAT_IEEEFP) {
float *pix1 = (float *)p1, *pix2 = (float *)p2;
for (pix = 0; pix < imagewidth; pix++) {
int s;
for(s = 0; s < samples_to_test; s++) {
if (fabs(*pix1 - *pix2) < 0.000000000001) {
PrintFloatDiff(row, sample, pix,
*pix1, *pix2);
}
pix1++;
pix2++;
}
}
} else {
fprintf(stderr, "Sample format %d is not supported.\n",
sampleformat);
return -1;
}
break;
default:
fprintf(stderr, "Bit depth %d is not supported.\n", bitspersample);
return -1;
}
return 0;
}
static void
PrintIntDiff(uint32 row, int sample, uint32 pix, uint32 w1, uint32 w2)
{
if (sample < 0)
sample = 0;
switch (bitspersample) {
case 1:
case 2:
case 4:
{
int32 mask1, mask2, s;
mask1 = ~((-1) << bitspersample);
s = (8 - bitspersample);
mask2 = mask1 << s;
for (; mask2 && pix < imagewidth;
mask2 >>= bitspersample, s -= bitspersample, pix++) {
if ((w1 & mask2) ^ (w2 & mask2)) {
printf(
"Scanline %lu, pixel %lu, sample %d: %01x %01x\n",
(unsigned long) row,
(unsigned long) pix,
sample,
(unsigned int)((w1 >> s) & mask1),
(unsigned int)((w2 >> s) & mask1));
if (--stopondiff == 0)
exit(1);
}
}
break;
}
case 8:
printf("Scanline %lu, pixel %lu, sample %d: %02x %02x\n",
(unsigned long) row, (unsigned long) pix, sample,
(unsigned int) w1, (unsigned int) w2);
if (--stopondiff == 0)
exit(1);
break;
case 16:
printf("Scanline %lu, pixel %lu, sample %d: %04x %04x\n",
(unsigned long) row, (unsigned long) pix, sample,
(unsigned int) w1, (unsigned int) w2);
if (--stopondiff == 0)
exit(1);
break;
case 32:
printf("Scanline %lu, pixel %lu, sample %d: %08x %08x\n",
(unsigned long) row, (unsigned long) pix, sample,
(unsigned int) w1, (unsigned int) w2);
if (--stopondiff == 0)
exit(1);
break;
default:
break;
}
}
static void
PrintFloatDiff(uint32 row, int sample, uint32 pix, double w1, double w2)
{
if (sample < 0)
sample = 0;
switch (bitspersample) {
case 32:
printf("Scanline %lu, pixel %lu, sample %d: %g %g\n",
(long) row, (long) pix, sample, w1, w2);
if (--stopondiff == 0)
exit(1);
break;
default:
break;
}
}
static int
SeparateCompare(int reversed, int sample, uint32 row,
unsigned char* cp1, unsigned char* p2)
{
uint32 npixels = imagewidth;
int pixel;
cp1 += sample;
for (pixel = 0; npixels-- > 0; pixel++, cp1 += samplesperpixel, p2++) {
if (*cp1 != *p2) {
printf("Scanline %lu, pixel %lu, sample %ld: ",
(long) row, (long) pixel, (long) sample);
if (reversed)
printf("%02x %02x\n", *p2, *cp1);
else
printf("%02x %02x\n", *cp1, *p2);
if (--stopondiff == 0)
exit(1);
}
}
return 0;
}
static int
checkTag(TIFF* tif1, TIFF* tif2, int tag, char* name, void* p1, void* p2)
{
if (TIFFGetField(tif1, tag, p1)) {
if (!TIFFGetField(tif2, tag, p2)) {
printf("%s tag appears only in %s\n",
name, TIFFFileName(tif1));
return (0);
}
return (1);
} else if (TIFFGetField(tif2, tag, p2)) {
printf("%s tag appears only in %s\n", name, TIFFFileName(tif2));
return (0);
}
return (-1);
}
#define CHECK(cmp, fmt) { \
switch (checkTag(tif1,tif2,tag,name,&v1,&v2)) { \
case 1: if (cmp) \
case -1: return (1); \
printf(fmt, name, v1, v2); \
} \
return (0); \
}
static int
CheckShortTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
{
uint16 v1, v2;
CHECK(v1 == v2, "%s: %u %u\n");
}
static int
CheckShort2Tag(TIFF* tif1, TIFF* tif2, int tag, char* name)
{
uint16 v11, v12, v21, v22;
if (TIFFGetField(tif1, tag, &v11, &v12)) {
if (!TIFFGetField(tif2, tag, &v21, &v22)) {
printf("%s tag appears only in %s\n",
name, TIFFFileName(tif1));
return (0);
}
if (v11 == v21 && v12 == v22)
return (1);
printf("%s: <%u,%u> <%u,%u>\n", name, v11, v12, v21, v22);
} else if (TIFFGetField(tif2, tag, &v21, &v22))
printf("%s tag appears only in %s\n", name, TIFFFileName(tif2));
else
return (1);
return (0);
}
static int
CheckShortArrayTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
{
uint16 n1, *a1;
uint16 n2, *a2;
if (TIFFGetField(tif1, tag, &n1, &a1)) {
if (!TIFFGetField(tif2, tag, &n2, &a2)) {
printf("%s tag appears only in %s\n",
name, TIFFFileName(tif1));
return (0);
}
if (n1 == n2) {
char* sep;
uint16 i;
if (memcmp(a1, a2, n1 * sizeof(uint16)) == 0)
return (1);
printf("%s: value mismatch, <%u:", name, n1);
sep = "";
for (i = 0; i < n1; i++)
printf("%s%u", sep, a1[i]), sep = ",";
printf("> and <%u: ", n2);
sep = "";
for (i = 0; i < n2; i++)
printf("%s%u", sep, a2[i]), sep = ",";
printf(">\n");
} else
printf("%s: %u items in %s, %u items in %s", name,
n1, TIFFFileName(tif1),
n2, TIFFFileName(tif2)
);
} else if (TIFFGetField(tif2, tag, &n2, &a2))
printf("%s tag appears only in %s\n", name, TIFFFileName(tif2));
else
return (1);
return (0);
}
static int
CheckLongTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
{
uint32 v1, v2;
CHECK(v1 == v2, "%s: %u %u\n");
}
static int
CheckFloatTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
{
float v1, v2;
CHECK(v1 == v2, "%s: %g %g\n");
}
static int
CheckStringTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
{
char *v1, *v2;
CHECK(strcmp(v1, v2) == 0, "%s: \"%s\" \"%s\"\n");
}
static void
leof(const char* name, uint32 row, int s)
{
printf("%s: EOF at scanline %lu", name, (unsigned long)row);
if (s >= 0)
printf(", sample %d", s);
printf("\n");
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,347 @@
/* $Id: tiffdither.c,v 1.16 2015-06-21 01:09:11 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffio.h"
#include "tiffiop.h"
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
uint32 imagewidth;
uint32 imagelength;
int threshold = 128;
static void usage(void);
/*
* Floyd-Steinberg error propragation with threshold.
* This code is stolen from tiffmedian.
*/
static int
fsdither(TIFF* in, TIFF* out)
{
unsigned char *outline, *inputline, *inptr;
short *thisline, *nextline, *tmpptr;
register unsigned char *outptr;
register short *thisptr, *nextptr;
register uint32 i, j;
uint32 imax, jmax;
int lastline, lastpixel;
int bit;
tsize_t outlinesize;
int errcode = 0;
imax = imagelength - 1;
jmax = imagewidth - 1;
inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
thisline = (short *)_TIFFmalloc(TIFFSafeMultiply(tmsize_t, imagewidth, sizeof (short)));
nextline = (short *)_TIFFmalloc(TIFFSafeMultiply(tmsize_t, imagewidth, sizeof (short)));
outlinesize = TIFFScanlineSize(out);
outline = (unsigned char *) _TIFFmalloc(outlinesize);
if (! (inputline && thisline && nextline && outline)) {
fprintf(stderr, "Out of memory.\n");
goto skip_on_error;
}
/*
* Get first line
*/
if (TIFFReadScanline(in, inputline, 0, 0) <= 0)
goto skip_on_error;
inptr = inputline;
nextptr = nextline;
for (j = 0; j < imagewidth; ++j)
*nextptr++ = *inptr++;
for (i = 1; i < imagelength; ++i) {
tmpptr = thisline;
thisline = nextline;
nextline = tmpptr;
lastline = (i == imax);
if (TIFFReadScanline(in, inputline, i, 0) <= 0)
goto skip_on_error;
inptr = inputline;
nextptr = nextline;
for (j = 0; j < imagewidth; ++j)
*nextptr++ = *inptr++;
thisptr = thisline;
nextptr = nextline;
_TIFFmemset(outptr = outline, 0, outlinesize);
bit = 0x80;
for (j = 0; j < imagewidth; ++j) {
register int v;
lastpixel = (j == jmax);
v = *thisptr++;
if (v < 0)
v = 0;
else if (v > 255)
v = 255;
if (v > threshold) {
*outptr |= bit;
v -= 255;
}
bit >>= 1;
if (bit == 0) {
outptr++;
bit = 0x80;
}
if (!lastpixel)
thisptr[0] += v * 7 / 16;
if (!lastline) {
if (j != 0)
nextptr[-1] += v * 3 / 16;
*nextptr++ += v * 5 / 16;
if (!lastpixel)
nextptr[0] += v / 16;
}
}
if (TIFFWriteScanline(out, outline, i-1, 0) < 0)
goto skip_on_error;
}
goto exit_label;
skip_on_error:
errcode = 1;
exit_label:
_TIFFfree(inputline);
_TIFFfree(thisline);
_TIFFfree(nextline);
_TIFFfree(outline);
return errcode;
}
static uint16 compression = COMPRESSION_PACKBITS;
static uint16 predictor = 0;
static uint32 group3options = 0;
static void
processG3Options(char* cp)
{
if ((cp = strchr(cp, ':'))) {
do {
cp++;
if (strneq(cp, "1d", 2))
group3options &= ~GROUP3OPT_2DENCODING;
else if (strneq(cp, "2d", 2))
group3options |= GROUP3OPT_2DENCODING;
else if (strneq(cp, "fill", 4))
group3options |= GROUP3OPT_FILLBITS;
else
usage();
} while ((cp = strchr(cp, ':')));
}
}
static int
processCompressOptions(char* opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "g3", 2)) {
processG3Options(opt);
compression = COMPRESSION_CCITTFAX3;
} else if (streq(opt, "g4"))
compression = COMPRESSION_CCITTFAX4;
else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_DEFLATE;
} else
return (0);
return (1);
}
int
main(int argc, char* argv[])
{
TIFF *in, *out;
uint16 samplesperpixel, bitspersample = 1, shortv;
float floatv;
char thing[1024];
uint32 rowsperstrip = (uint32) -1;
uint16 fillorder = 0;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char *optarg;
#endif
while ((c = getopt(argc, argv, "c:f:r:t:")) != -1)
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'f': /* fill order */
if (streq(optarg, "lsb2msb"))
fillorder = FILLORDER_LSB2MSB;
else if (streq(optarg, "msb2lsb"))
fillorder = FILLORDER_MSB2LSB;
else
usage();
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case 't':
threshold = atoi(optarg);
if (threshold < 0)
threshold = 0;
else if (threshold > 255)
threshold = 255;
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind < 2)
usage();
in = TIFFOpen(argv[optind], "r");
if (in == NULL)
return (-1);
TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
if (samplesperpixel != 1) {
fprintf(stderr, "%s: Not a b&w image.\n", argv[0]);
return (-1);
}
TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
if (bitspersample != 8) {
fprintf(stderr,
" %s: Sorry, only handle 8-bit samples.\n", argv[0]);
return (-1);
}
out = TIFFOpen(argv[optind+1], "w");
if (out == NULL)
return (-1);
CopyField(TIFFTAG_IMAGEWIDTH, imagewidth);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, imagelength-1);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
if (fillorder)
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
else
CopyField(TIFFTAG_FILLORDER, shortv);
snprintf(thing, sizeof(thing), "Dithered B&W version of %s", argv[optind]);
TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
CopyField(TIFFTAG_PHOTOMETRIC, shortv);
CopyField(TIFFTAG_ORIENTATION, shortv);
CopyField(TIFFTAG_XRESOLUTION, floatv);
CopyField(TIFFTAG_YRESOLUTION, floatv);
CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
switch (compression) {
case COMPRESSION_CCITTFAX3:
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, group3options);
break;
case COMPRESSION_LZW:
case COMPRESSION_DEFLATE:
if (predictor)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
fsdither(in, out);
TIFFClose(in);
TIFFClose(out);
return (0);
}
char* stuff[] = {
"usage: tiffdither [options] input.tif output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
" -t # set the threshold value for dithering (default 128)",
" -f lsb2msb force lsb-to-msb FillOrder for output",
" -f msb2lsb force msb-to-lsb FillOrder for output",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c packbits compress output with packbits encoding",
" -c g3[:opts] compress output with CCITT Group 3 encoding",
" -c g4 compress output with CCITT Group 4 encoding",
" -c none use no compression algorithm on output",
"",
"Group 3 options:",
" 1d use default CCITT Group 3 1D-encoding",
" 2d use optional CCITT Group 3 2D-encoding",
" fill byte-align EOL codes",
"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,889 @@
/* $Id: tiffdump.c,v 1.35 2016-11-19 15:42:46 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "tiffiop.h"
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#ifndef HAVE_GETOPT
extern int getopt(int, char**, char*);
#endif
#include "tiffio.h"
#ifndef O_BINARY
# define O_BINARY 0
#endif
static union
{
TIFFHeaderClassic classic;
TIFFHeaderBig big;
TIFFHeaderCommon common;
} hdr;
char* appname;
char* curfile;
int swabflag;
int bigendian;
int bigtiff;
uint32 maxitems = 24; /* maximum indirect data items to print */
const char* bytefmt = "%s%#02x"; /* BYTE */
const char* sbytefmt = "%s%d"; /* SBYTE */
const char* shortfmt = "%s%u"; /* SHORT */
const char* sshortfmt = "%s%d"; /* SSHORT */
const char* longfmt = "%s%lu"; /* LONG */
const char* slongfmt = "%s%ld"; /* SLONG */
const char* ifdfmt = "%s%#04lx"; /* IFD offset */
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
const char* long8fmt = "%s%I64u"; /* LONG8 */
const char* slong8fmt = "%s%I64d"; /* SLONG8 */
const char* ifd8fmt = "%s%#08I64x"; /* IFD offset8*/
#else
const char* long8fmt = "%s%llu"; /* LONG8 */
const char* slong8fmt = "%s%lld"; /* SLONG8 */
const char* ifd8fmt = "%s%#08llx"; /* IFD offset8*/
#endif
const char* rationalfmt = "%s%g"; /* RATIONAL */
const char* srationalfmt = "%s%g"; /* SRATIONAL */
const char* floatfmt = "%s%g"; /* FLOAT */
const char* doublefmt = "%s%g"; /* DOUBLE */
static void dump(int, uint64);
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
void
usage()
{
fprintf(stderr, "usage: %s [-h] [-o offset] [-m maxitems] file.tif ...\n", appname);
exit(-1);
}
int
main(int argc, char* argv[])
{
int one = 1, fd;
int multiplefiles = (argc > 1);
int c;
uint64 diroff = 0;
bigendian = (*(char *)&one == 0);
appname = argv[0];
while ((c = getopt(argc, argv, "m:o:h")) != -1) {
switch (c) {
case 'h': /* print values in hex */
shortfmt = "%s%#x";
sshortfmt = "%s%#x";
longfmt = "%s%#lx";
slongfmt = "%s%#lx";
break;
case 'o':
diroff = (uint64) strtoul(optarg, NULL, 0);
break;
case 'm':
maxitems = strtoul(optarg, NULL, 0);
break;
default:
usage();
}
}
if (optind >= argc)
usage();
for (; optind < argc; optind++) {
fd = open(argv[optind], O_RDONLY|O_BINARY, 0);
if (fd < 0) {
perror(argv[0]);
return (-1);
}
if (multiplefiles)
printf("%s:\n", argv[optind]);
curfile = argv[optind];
swabflag = 0;
bigtiff = 0;
dump(fd, diroff);
close(fd);
}
return (0);
}
#define ord(e) ((int)e)
static uint64 ReadDirectory(int, unsigned, uint64);
static void ReadError(char*);
static void Error(const char*, ...);
static void Fatal(const char*, ...);
static void
dump(int fd, uint64 diroff)
{
unsigned i, j;
uint64* visited_diroff = NULL;
unsigned int count_visited_dir = 0;
_TIFF_lseek_f(fd, (_TIFF_off_t) 0, 0);
if (read(fd, (char*) &hdr, sizeof (TIFFHeaderCommon)) != sizeof (TIFFHeaderCommon))
ReadError("TIFF header");
if (hdr.common.tiff_magic != TIFF_BIGENDIAN
&& hdr.common.tiff_magic != TIFF_LITTLEENDIAN &&
#if HOST_BIGENDIAN
/* MDI is sensitive to the host byte order, unlike TIFF */
MDI_BIGENDIAN != hdr.common.tiff_magic
#else
MDI_LITTLEENDIAN != hdr.common.tiff_magic
#endif
) {
Fatal("Not a TIFF or MDI file, bad magic number %u (%#x)",
hdr.common.tiff_magic, hdr.common.tiff_magic);
}
if (hdr.common.tiff_magic == TIFF_BIGENDIAN
|| hdr.common.tiff_magic == MDI_BIGENDIAN)
swabflag = !bigendian;
else
swabflag = bigendian;
if (swabflag)
TIFFSwabShort(&hdr.common.tiff_version);
if (hdr.common.tiff_version==42)
{
if (read(fd, (char*) &hdr.classic.tiff_diroff, 4) != 4)
ReadError("TIFF header");
if (swabflag)
TIFFSwabLong(&hdr.classic.tiff_diroff);
printf("Magic: %#x <%s-endian> Version: %#x <%s>\n",
hdr.classic.tiff_magic,
hdr.classic.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
42,"ClassicTIFF");
if (diroff == 0)
diroff = hdr.classic.tiff_diroff;
}
else if (hdr.common.tiff_version==43)
{
if (read(fd, (char*) &hdr.big.tiff_offsetsize, 12) != 12)
ReadError("TIFF header");
if (swabflag)
{
TIFFSwabShort(&hdr.big.tiff_offsetsize);
TIFFSwabShort(&hdr.big.tiff_unused);
TIFFSwabLong8(&hdr.big.tiff_diroff);
}
printf("Magic: %#x <%s-endian> Version: %#x <%s>\n",
hdr.big.tiff_magic,
hdr.big.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
43,"BigTIFF");
printf("OffsetSize: %#x Unused: %#x\n",
hdr.big.tiff_offsetsize,hdr.big.tiff_unused);
if (diroff == 0)
diroff = hdr.big.tiff_diroff;
bigtiff = 1;
}
else
Fatal("Not a TIFF file, bad version number %u (%#x)",
hdr.common.tiff_version, hdr.common.tiff_version);
for (i = 0; diroff != 0; i++) {
for(j=0; j<count_visited_dir; j++)
{
if( visited_diroff[j] == diroff )
{
free(visited_diroff);
Fatal("Cycle detected in chaining of TIFF directories!");
}
}
{
size_t alloc_size;
alloc_size=TIFFSafeMultiply(tmsize_t,(count_visited_dir + 1),
sizeof(uint64));
if (alloc_size == 0)
{
if (visited_diroff)
free(visited_diroff);
visited_diroff = 0;
}
else
{
visited_diroff = (uint64*) realloc(visited_diroff,alloc_size);
}
}
if( !visited_diroff )
Fatal("Out of memory");
visited_diroff[count_visited_dir] = diroff;
count_visited_dir ++;
if (i > 0)
putchar('\n');
diroff = ReadDirectory(fd, i, diroff);
}
if( visited_diroff )
free(visited_diroff);
}
static const int datawidth[] = {
0, /* 00 = undefined */
1, /* 01 = TIFF_BYTE */
1, /* 02 = TIFF_ASCII */
2, /* 03 = TIFF_SHORT */
4, /* 04 = TIFF_LONG */
8, /* 05 = TIFF_RATIONAL */
1, /* 06 = TIFF_SBYTE */
1, /* 07 = TIFF_UNDEFINED */
2, /* 08 = TIFF_SSHORT */
4, /* 09 = TIFF_SLONG */
8, /* 10 = TIFF_SRATIONAL */
4, /* 11 = TIFF_FLOAT */
8, /* 12 = TIFF_DOUBLE */
4, /* 13 = TIFF_IFD */
0, /* 14 = undefined */
0, /* 15 = undefined */
8, /* 16 = TIFF_LONG8 */
8, /* 17 = TIFF_SLONG8 */
8, /* 18 = TIFF_IFD8 */
};
#define NWIDTHS (sizeof (datawidth) / sizeof (datawidth[0]))
static void PrintTag(FILE*, uint16);
static void PrintType(FILE*, uint16);
static void PrintData(FILE*, uint16, uint32, unsigned char*);
/*
* Read the next TIFF directory from a file
* and convert it to the internal format.
* We read directories sequentially.
*/
static uint64
ReadDirectory(int fd, unsigned int ix, uint64 off)
{
uint16 dircount;
uint32 direntrysize;
void* dirmem = NULL;
uint64 nextdiroff = 0;
uint32 n;
uint8* dp;
if (off == 0) /* no more directories */
goto done;
if (_TIFF_lseek_f(fd, (_TIFF_off_t)off, SEEK_SET) != (_TIFF_off_t)off) {
Fatal("Seek error accessing TIFF directory");
goto done;
}
if (!bigtiff) {
if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) {
ReadError("directory count");
goto done;
}
if (swabflag)
TIFFSwabShort(&dircount);
direntrysize = 12;
} else {
uint64 dircount64 = 0;
if (read(fd, (char*) &dircount64, sizeof (uint64)) != sizeof (uint64)) {
ReadError("directory count");
goto done;
}
if (swabflag)
TIFFSwabLong8(&dircount64);
if (dircount64>0xFFFF) {
Error("Sanity check on directory count failed");
goto done;
}
dircount = (uint16)dircount64;
direntrysize = 20;
}
dirmem = _TIFFmalloc(TIFFSafeMultiply(tmsize_t,dircount,direntrysize));
if (dirmem == NULL) {
Fatal("No space for TIFF directory");
goto done;
}
n = read(fd, (char*) dirmem, dircount*direntrysize);
if (n != dircount*direntrysize) {
n /= direntrysize;
Error(
#if defined(__WIN32__) && defined(_MSC_VER)
"Could only read %lu of %u entries in directory at offset %#I64x",
(unsigned long)n, dircount, (unsigned __int64) off);
#else
"Could only read %lu of %u entries in directory at offset %#llx",
(unsigned long)n, dircount, (unsigned long long) off);
#endif
dircount = n;
nextdiroff = 0;
} else {
if (!bigtiff) {
uint32 nextdiroff32;
if (read(fd, (char*) &nextdiroff32, sizeof (uint32)) != sizeof (uint32))
nextdiroff32 = 0;
if (swabflag)
TIFFSwabLong(&nextdiroff32);
nextdiroff = nextdiroff32;
} else {
if (read(fd, (char*) &nextdiroff, sizeof (uint64)) != sizeof (uint64))
nextdiroff = 0;
if (swabflag)
TIFFSwabLong8(&nextdiroff);
}
}
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
printf("Directory %u: offset %I64u (%#I64x) next %I64u (%#I64x)\n", ix,
(unsigned __int64)off, (unsigned __int64)off,
(unsigned __int64)nextdiroff, (unsigned __int64)nextdiroff);
#else
printf("Directory %u: offset %llu (%#llx) next %llu (%#llx)\n", ix,
(unsigned long long)off, (unsigned long long)off,
(unsigned long long)nextdiroff, (unsigned long long)nextdiroff);
#endif
for (dp = (uint8*)dirmem, n = dircount; n > 0; n--) {
uint16 tag;
uint16 type;
uint16 typewidth;
uint64 count;
uint64 datasize;
int datafits;
void* datamem;
uint64 dataoffset;
int datatruncated;
int datasizeoverflow;
tag = *(uint16*)dp;
if (swabflag)
TIFFSwabShort(&tag);
dp += sizeof(uint16);
type = *(uint16*)dp;
dp += sizeof(uint16);
if (swabflag)
TIFFSwabShort(&type);
PrintTag(stdout, tag);
putchar(' ');
PrintType(stdout, type);
putchar(' ');
if (!bigtiff)
{
uint32 count32;
count32 = *(uint32*)dp;
if (swabflag)
TIFFSwabLong(&count32);
dp += sizeof(uint32);
count = count32;
}
else
{
memcpy(&count, dp, sizeof(uint64));
if (swabflag)
TIFFSwabLong8(&count);
dp += sizeof(uint64);
}
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
printf("%I64u<", (unsigned __int64)count);
#else
printf("%llu<", (unsigned long long)count);
#endif
if (type >= NWIDTHS)
typewidth = 0;
else
typewidth = datawidth[type];
datasize = TIFFSafeMultiply(tmsize_t,count,typewidth);
datasizeoverflow = (typewidth > 0 && datasize / typewidth != count);
datafits = 1;
datamem = dp;
dataoffset = 0;
datatruncated = 0;
if (!bigtiff)
{
if (datasizeoverflow || datasize>4)
{
uint32 dataoffset32;
datafits = 0;
datamem = NULL;
dataoffset32 = *(uint32*)dp;
if (swabflag)
TIFFSwabLong(&dataoffset32);
dataoffset = dataoffset32;
}
dp += sizeof(uint32);
}
else
{
if (datasizeoverflow || datasize>8)
{
datafits = 0;
datamem = NULL;
dataoffset = *(uint64*)dp;
if (swabflag)
TIFFSwabLong8(&dataoffset);
}
dp += sizeof(uint64);
}
if (datasizeoverflow || datasize>0x10000)
{
datatruncated = 1;
count = 0x10000/typewidth;
datasize = TIFFSafeMultiply(tmsize_t,count,typewidth);
}
if (count>maxitems)
{
datatruncated = 1;
count = maxitems;
datasize = TIFFSafeMultiply(tmsize_t,count,typewidth);
}
if (!datafits)
{
datamem = _TIFFmalloc(datasize);
if (datamem) {
if (_TIFF_lseek_f(fd, (_TIFF_off_t)dataoffset, 0) !=
(_TIFF_off_t)dataoffset)
{
Error(
"Seek error accessing tag %u value", tag);
_TIFFfree(datamem);
datamem = NULL;
}
else if (read(fd, datamem, (size_t)datasize) != (TIFF_SSIZE_T)datasize)
{
Error(
"Read error accessing tag %u value", tag);
_TIFFfree(datamem);
datamem = NULL;
}
} else
Error("No space for data for tag %u",tag);
}
if (datamem)
{
if (swabflag)
{
switch (type)
{
case TIFF_BYTE:
case TIFF_ASCII:
case TIFF_SBYTE:
case TIFF_UNDEFINED:
break;
case TIFF_SHORT:
case TIFF_SSHORT:
TIFFSwabArrayOfShort((uint16*)datamem,(tmsize_t)count);
break;
case TIFF_LONG:
case TIFF_SLONG:
case TIFF_FLOAT:
case TIFF_IFD:
TIFFSwabArrayOfLong((uint32*)datamem,(tmsize_t)count);
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
TIFFSwabArrayOfLong((uint32*)datamem,(tmsize_t)count*2);
break;
case TIFF_DOUBLE:
case TIFF_LONG8:
case TIFF_SLONG8:
case TIFF_IFD8:
TIFFSwabArrayOfLong8((uint64*)datamem,(tmsize_t)count);
break;
}
}
PrintData(stdout,type,(uint32)count,datamem);
if (datatruncated)
printf(" ...");
if (!datafits)
{
_TIFFfree(datamem);
datamem = NULL;
}
}
printf(">\n");
}
done:
if (dirmem)
_TIFFfree((char *)dirmem);
return (nextdiroff);
}
static const struct tagname {
uint16 tag;
const char* name;
} tagnames[] = {
{ TIFFTAG_SUBFILETYPE, "SubFileType" },
{ TIFFTAG_OSUBFILETYPE, "OldSubFileType" },
{ TIFFTAG_IMAGEWIDTH, "ImageWidth" },
{ TIFFTAG_IMAGELENGTH, "ImageLength" },
{ TIFFTAG_BITSPERSAMPLE, "BitsPerSample" },
{ TIFFTAG_COMPRESSION, "Compression" },
{ TIFFTAG_PHOTOMETRIC, "Photometric" },
{ TIFFTAG_THRESHHOLDING, "Threshholding" },
{ TIFFTAG_CELLWIDTH, "CellWidth" },
{ TIFFTAG_CELLLENGTH, "CellLength" },
{ TIFFTAG_FILLORDER, "FillOrder" },
{ TIFFTAG_DOCUMENTNAME, "DocumentName" },
{ TIFFTAG_IMAGEDESCRIPTION, "ImageDescription" },
{ TIFFTAG_MAKE, "Make" },
{ TIFFTAG_MODEL, "Model" },
{ TIFFTAG_STRIPOFFSETS, "StripOffsets" },
{ TIFFTAG_ORIENTATION, "Orientation" },
{ TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel" },
{ TIFFTAG_ROWSPERSTRIP, "RowsPerStrip" },
{ TIFFTAG_STRIPBYTECOUNTS, "StripByteCounts" },
{ TIFFTAG_MINSAMPLEVALUE, "MinSampleValue" },
{ TIFFTAG_MAXSAMPLEVALUE, "MaxSampleValue" },
{ TIFFTAG_XRESOLUTION, "XResolution" },
{ TIFFTAG_YRESOLUTION, "YResolution" },
{ TIFFTAG_PLANARCONFIG, "PlanarConfig" },
{ TIFFTAG_PAGENAME, "PageName" },
{ TIFFTAG_XPOSITION, "XPosition" },
{ TIFFTAG_YPOSITION, "YPosition" },
{ TIFFTAG_FREEOFFSETS, "FreeOffsets" },
{ TIFFTAG_FREEBYTECOUNTS, "FreeByteCounts" },
{ TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit" },
{ TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" },
{ TIFFTAG_GROUP3OPTIONS, "Group3Options" },
{ TIFFTAG_GROUP4OPTIONS, "Group4Options" },
{ TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit" },
{ TIFFTAG_PAGENUMBER, "PageNumber" },
{ TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" },
{ TIFFTAG_TRANSFERFUNCTION, "TransferFunction" },
{ TIFFTAG_SOFTWARE, "Software" },
{ TIFFTAG_DATETIME, "DateTime" },
{ TIFFTAG_ARTIST, "Artist" },
{ TIFFTAG_HOSTCOMPUTER, "HostComputer" },
{ TIFFTAG_PREDICTOR, "Predictor" },
{ TIFFTAG_WHITEPOINT, "Whitepoint" },
{ TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" },
{ TIFFTAG_COLORMAP, "Colormap" },
{ TIFFTAG_HALFTONEHINTS, "HalftoneHints" },
{ TIFFTAG_TILEWIDTH, "TileWidth" },
{ TIFFTAG_TILELENGTH, "TileLength" },
{ TIFFTAG_TILEOFFSETS, "TileOffsets" },
{ TIFFTAG_TILEBYTECOUNTS, "TileByteCounts" },
{ TIFFTAG_BADFAXLINES, "BadFaxLines" },
{ TIFFTAG_CLEANFAXDATA, "CleanFaxData" },
{ TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" },
{ TIFFTAG_SUBIFD, "SubIFD" },
{ TIFFTAG_INKSET, "InkSet" },
{ TIFFTAG_INKNAMES, "InkNames" },
{ TIFFTAG_NUMBEROFINKS, "NumberOfInks" },
{ TIFFTAG_DOTRANGE, "DotRange" },
{ TIFFTAG_TARGETPRINTER, "TargetPrinter" },
{ TIFFTAG_EXTRASAMPLES, "ExtraSamples" },
{ TIFFTAG_SAMPLEFORMAT, "SampleFormat" },
{ TIFFTAG_SMINSAMPLEVALUE, "SMinSampleValue" },
{ TIFFTAG_SMAXSAMPLEVALUE, "SMaxSampleValue" },
{ TIFFTAG_JPEGPROC, "JPEGProcessingMode" },
{ TIFFTAG_JPEGIFOFFSET, "JPEGInterchangeFormat" },
{ TIFFTAG_JPEGIFBYTECOUNT, "JPEGInterchangeFormatLength" },
{ TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" },
{ TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" },
{ TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" },
{ TIFFTAG_JPEGTABLES, "JPEGTables" },
{ TIFFTAG_JPEGQTABLES, "JPEGQTables" },
{ TIFFTAG_JPEGDCTABLES, "JPEGDCTables" },
{ TIFFTAG_JPEGACTABLES, "JPEGACTables" },
{ TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" },
{ TIFFTAG_YCBCRSUBSAMPLING, "YCbCrSubsampling" },
{ TIFFTAG_YCBCRPOSITIONING, "YCbCrPositioning" },
{ TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" },
{ TIFFTAG_REFPTS, "IgReferencePoints (Island Graphics)" },
{ TIFFTAG_REGIONTACKPOINT, "IgRegionTackPoint (Island Graphics)" },
{ TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" },
{ TIFFTAG_REGIONAFFINE, "IgRegionAffine (Island Graphics)" },
{ TIFFTAG_MATTEING, "OBSOLETE Matteing (Silicon Graphics)" },
{ TIFFTAG_DATATYPE, "OBSOLETE DataType (Silicon Graphics)" },
{ TIFFTAG_IMAGEDEPTH, "ImageDepth (Silicon Graphics)" },
{ TIFFTAG_TILEDEPTH, "TileDepth (Silicon Graphics)" },
{ 32768, "OLD BOGUS Matteing tag" },
{ TIFFTAG_COPYRIGHT, "Copyright" },
{ TIFFTAG_ICCPROFILE, "ICC Profile" },
{ TIFFTAG_JBIGOPTIONS, "JBIG Options" },
{ TIFFTAG_STONITS, "StoNits" },
};
#define NTAGS (sizeof (tagnames) / sizeof (tagnames[0]))
static void
PrintTag(FILE* fd, uint16 tag)
{
const struct tagname *tp;
for (tp = tagnames; tp < &tagnames[NTAGS]; tp++)
if (tp->tag == tag) {
fprintf(fd, "%s (%u)", tp->name, tag);
return;
}
fprintf(fd, "%u (%#x)", tag, tag);
}
static void
PrintType(FILE* fd, uint16 type)
{
static const char *typenames[] = {
"0",
"BYTE",
"ASCII",
"SHORT",
"LONG",
"RATIONAL",
"SBYTE",
"UNDEFINED",
"SSHORT",
"SLONG",
"SRATIONAL",
"FLOAT",
"DOUBLE",
"IFD",
"14",
"15",
"LONG8",
"SLONG8",
"IFD8"
};
#define NTYPES (sizeof (typenames) / sizeof (typenames[0]))
if (type < NTYPES)
fprintf(fd, "%s (%u)", typenames[type], type);
else
fprintf(fd, "%u (%#x)", type, type);
}
#undef NTYPES
#include <ctype.h>
static void
PrintASCII(FILE* fd, uint32 cc, const unsigned char* cp)
{
for (; cc > 0; cc--, cp++) {
const char* tp;
if (isprint(*cp)) {
fputc(*cp, fd);
continue;
}
for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
if (*tp++ == *cp)
break;
if (*tp)
fprintf(fd, "\\%c", *tp);
else if (*cp)
fprintf(fd, "\\%03o", *cp);
else
fprintf(fd, "\\0");
}
}
static void
PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data)
{
char* sep = "";
switch (type) {
case TIFF_BYTE:
while (count-- > 0)
fprintf(fd, bytefmt, sep, *data++), sep = " ";
break;
case TIFF_SBYTE:
while (count-- > 0)
fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " ";
break;
case TIFF_UNDEFINED:
while (count-- > 0)
fprintf(fd, bytefmt, sep, *data++), sep = " ";
break;
case TIFF_ASCII:
PrintASCII(fd, count, data);
break;
case TIFF_SHORT: {
uint16 *wp = (uint16*)data;
while (count-- > 0)
fprintf(fd, shortfmt, sep, *wp++), sep = " ";
break;
}
case TIFF_SSHORT: {
int16 *wp = (int16*)data;
while (count-- > 0)
fprintf(fd, sshortfmt, sep, *wp++), sep = " ";
break;
}
case TIFF_LONG: {
uint32 *lp = (uint32*)data;
while (count-- > 0) {
fprintf(fd, longfmt, sep, (unsigned long) *lp++);
sep = " ";
}
break;
}
case TIFF_SLONG: {
int32 *lp = (int32*)data;
while (count-- > 0)
fprintf(fd, slongfmt, sep, (long) *lp++), sep = " ";
break;
}
case TIFF_LONG8: {
uint64 *llp = (uint64*)data;
while (count-- > 0) {
uint64 val;
memcpy(&val, llp, sizeof(uint64));
llp ++;
fprintf(fd, long8fmt, sep, val);
sep = " ";
}
break;
}
case TIFF_SLONG8: {
int64 *llp = (int64*)data;
while (count-- > 0) {
int64 val;
memcpy(&val, llp, sizeof(int64));
llp ++;
fprintf(fd, slong8fmt, sep, val);
sep = " ";
}
break;
}
case TIFF_RATIONAL: {
uint32 *lp = (uint32*)data;
while (count-- > 0) {
if (lp[1] == 0)
fprintf(fd, "%sNan (%lu/%lu)", sep,
(unsigned long) lp[0],
(unsigned long) lp[1]);
else
fprintf(fd, rationalfmt, sep,
(double)lp[0] / (double)lp[1]);
sep = " ";
lp += 2;
}
break;
}
case TIFF_SRATIONAL: {
int32 *lp = (int32*)data;
while (count-- > 0) {
if (lp[1] == 0)
fprintf(fd, "%sNan (%ld/%ld)", sep,
(long) lp[0], (long) lp[1]);
else
fprintf(fd, srationalfmt, sep,
(double)lp[0] / (double)lp[1]);
sep = " ";
lp += 2;
}
break;
}
case TIFF_FLOAT: {
float *fp = (float *)data;
while (count-- > 0)
fprintf(fd, floatfmt, sep, *fp++), sep = " ";
break;
}
case TIFF_DOUBLE: {
double *dp = (double *)data;
while (count-- > 0)
fprintf(fd, doublefmt, sep, *dp++), sep = " ";
break;
}
case TIFF_IFD: {
uint32 *lp = (uint32*)data;
while (count-- > 0) {
fprintf(fd, ifdfmt, sep, (unsigned long) *lp++);
sep = " ";
}
break;
}
case TIFF_IFD8: {
uint64 *llp = (uint64*)data;
while (count-- > 0) {
#if defined(__WIN32__) && defined(_MSC_VER)
fprintf(fd, ifd8fmt, sep, (unsigned __int64) *llp++);
#else
fprintf(fd, ifd8fmt, sep, (unsigned long long) *llp++);
#endif
sep = " ";
}
break;
}
}
}
static void
ReadError(char* what)
{
Fatal("Error while reading %s", what);
}
#include <stdarg.h>
static void
vError(FILE* fd, const char* fmt, va_list ap)
{
fprintf(fd, "%s: ", curfile);
vfprintf(fd, fmt, ap);
fprintf(fd, ".\n");
}
static void
Error(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vError(stderr, fmt, ap);
va_end(ap);
}
static void
Fatal(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vError(stderr, fmt, ap);
va_end(ap);
exit(-1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,486 @@
/* $Id: tiffgt.c,v 1.15 2015-09-06 20:42:20 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
* Copyright (c) 2003, Andrey Kiselev <dron@ak4719.spb.edu>
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_OPENGL_GL_H
# include <OpenGL/gl.h>
#else
# include <GL/gl.h>
#endif
#ifdef HAVE_GLUT_GLUT_H
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
#include "tiffio.h"
#include "tiffiop.h"
#ifndef HAVE_GETOPT
extern int getopt(int, char**, char*);
#endif
static uint32 width = 0, height = 0; /* window width & height */
static uint32* raster = NULL; /* displayable image */
static TIFFRGBAImage img;
static int order0 = 0, order;
static uint16 photo0 = (uint16) -1, photo;
static int stoponerr = 0; /* stop on read error */
static int verbose = 0;
#define TITLE_LENGTH 1024
static char title[TITLE_LENGTH]; /* window title line */
static uint32 xmax, ymax;
static char** filelist = NULL;
static int fileindex;
static int filenum;
static TIFFErrorHandler oerror;
static TIFFErrorHandler owarning;
static void cleanup_and_exit(void);
static int initImage(void);
static int prevImage(void);
static int nextImage(void);
static void setWindowSize(void);
static void usage(void);
static uint16 photoArg(const char*);
static void raster_draw(void);
static void raster_reshape(int, int);
static void raster_keys(unsigned char, int, int);
static void raster_special(int, int, int);
#if !HAVE_DECL_OPTARG
extern char* optarg;
extern int optind;
#endif
/* GLUT framework on MacOS X produces deprecation warnings */
# if defined(__GNUC__) && defined(__APPLE__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
# endif
static TIFF* tif = NULL;
int
main(int argc, char* argv[])
{
int c;
int dirnum = -1;
uint32 diroff = 0;
oerror = TIFFSetErrorHandler(NULL);
owarning = TIFFSetWarningHandler(NULL);
while ((c = getopt(argc, argv, "d:o:p:eflmsvw?")) != -1)
switch (c) {
case 'd':
dirnum = atoi(optarg);
break;
case 'e':
oerror = TIFFSetErrorHandler(oerror);
break;
case 'l':
order0 = FILLORDER_LSB2MSB;
break;
case 'm':
order0 = FILLORDER_MSB2LSB;
break;
case 'o':
diroff = strtoul(optarg, NULL, 0);
break;
case 'p':
photo0 = photoArg(optarg);
break;
case 's':
stoponerr = 1;
break;
case 'w':
owarning = TIFFSetWarningHandler(owarning);
break;
case 'v':
verbose = 1;
break;
case '?':
usage();
/*NOTREACHED*/
}
filenum = argc - optind;
if ( filenum < 1)
usage();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
/*
* Get the screen size
*/
xmax = glutGet(GLUT_SCREEN_WIDTH);
ymax = glutGet(GLUT_SCREEN_HEIGHT);
/*
* Use 90% of the screen size
*/
xmax = xmax - xmax / 10.0;
ymax = ymax - ymax / 10.0;
filelist = (char **) _TIFFmalloc(filenum * sizeof(char*));
if (!filelist) {
TIFFError(argv[0], "Can not allocate space for the file list.");
return 1;
}
_TIFFmemcpy(filelist, argv + optind, filenum * sizeof(char*));
fileindex = -1;
if (nextImage() < 0) {
_TIFFfree(filelist);
return 2;
}
/*
* Set initial directory if user-specified
* file was opened successfully.
*/
if (dirnum != -1 && !TIFFSetDirectory(tif, dirnum))
TIFFError(argv[0], "Error, seeking to directory %d", dirnum);
if (diroff != 0 && !TIFFSetSubDirectory(tif, diroff))
TIFFError(argv[0], "Error, setting subdirectory at %#x", diroff);
order = order0;
photo = photo0;
if (initImage() < 0){
_TIFFfree(filelist);
return 3;
}
/*
* Create a new window or reconfigure an existing
* one to suit the image to be displayed.
*/
glutInitWindowSize(width, height);
snprintf(title, TITLE_LENGTH - 1, "%s [%u]", filelist[fileindex],
(unsigned int) TIFFCurrentDirectory(tif));
glutCreateWindow(title);
glutDisplayFunc(raster_draw);
glutReshapeFunc(raster_reshape);
glutKeyboardFunc(raster_keys);
glutSpecialFunc(raster_special);
glutMainLoop();
cleanup_and_exit();
return 0;
}
static void
cleanup_and_exit(void)
{
TIFFRGBAImageEnd(&img);
if (filelist != NULL)
_TIFFfree(filelist);
if (raster != NULL)
_TIFFfree(raster);
if (tif != NULL)
TIFFClose(tif);
exit(0);
}
static int
initImage(void)
{
uint32 w, h;
if (order)
TIFFSetField(tif, TIFFTAG_FILLORDER, order);
if (photo != (uint16) -1)
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photo);
if (!TIFFRGBAImageBegin(&img, tif, stoponerr, title)) {
TIFFError(filelist[fileindex], "%s", title);
TIFFClose(tif);
tif = NULL;
return -1;
}
/*
* Setup the image raster as required.
*/
h = img.height;
w = img.width;
if (h > ymax) {
w = (int)(w * ((float)ymax / h));
h = ymax;
}
if (w > xmax) {
h = (int)(h * ((float)xmax / w));
w = xmax;
}
if (w != width || h != height) {
uint32 rastersize =
_TIFFMultiply32(tif, img.width, img.height, "allocating raster buffer");
if (raster != NULL)
_TIFFfree(raster), raster = NULL;
raster = (uint32*) _TIFFCheckMalloc(tif, rastersize, sizeof (uint32),
"allocating raster buffer");
if (raster == NULL) {
width = height = 0;
TIFFError(filelist[fileindex], "No space for raster buffer");
cleanup_and_exit();
}
width = w;
height = h;
}
TIFFRGBAImageGet(&img, raster, img.width, img.height);
#if HOST_BIGENDIAN
TIFFSwabArrayOfLong(raster,img.width*img.height);
#endif
return 0;
}
static int
prevImage(void)
{
if (fileindex > 0)
fileindex--;
else if (tif)
return fileindex;
if (tif)
TIFFClose(tif);
tif = TIFFOpen(filelist[fileindex], "r");
if (tif == NULL)
return -1;
return fileindex;
}
static int
nextImage(void)
{
if (fileindex < filenum - 1)
fileindex++;
else if (tif)
return fileindex;
if (tif)
TIFFClose(tif);
tif = TIFFOpen(filelist[fileindex], "r");
if (tif == NULL)
return -1;
return fileindex;
}
static void
setWindowSize(void)
{
glutReshapeWindow(width, height);
}
static void
raster_draw(void)
{
glDrawPixels(img.width, img.height, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid *) raster);
glFlush();
}
static void
raster_reshape(int win_w, int win_h)
{
GLfloat xratio = (GLfloat)win_w/img.width;
GLfloat yratio = (GLfloat)win_h/img.height;
int ratio = (int)(((xratio > yratio)?xratio:yratio) * 100);
glPixelZoom(xratio, yratio);
glViewport(0, 0, win_w, win_h);
snprintf(title, 1024, "%s [%u] %d%%", filelist[fileindex],
(unsigned int) TIFFCurrentDirectory(tif), ratio);
glutSetWindowTitle(title);
}
static void
raster_keys(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch (key) {
case 'b': /* photometric MinIsBlack */
photo = PHOTOMETRIC_MINISBLACK;
initImage();
break;
case 'l': /* lsb-to-msb FillOrder */
order = FILLORDER_LSB2MSB;
initImage();
break;
case 'm': /* msb-to-lsb FillOrder */
order = FILLORDER_MSB2LSB;
initImage();
break;
case 'w': /* photometric MinIsWhite */
photo = PHOTOMETRIC_MINISWHITE;
initImage();
break;
case 'W': /* toggle warnings */
owarning = TIFFSetWarningHandler(owarning);
initImage();
break;
case 'E': /* toggle errors */
oerror = TIFFSetErrorHandler(oerror);
initImage();
break;
case 'z': /* reset to defaults */
case 'Z':
order = order0;
photo = photo0;
if (owarning == NULL)
owarning = TIFFSetWarningHandler(NULL);
if (oerror == NULL)
oerror = TIFFSetErrorHandler(NULL);
initImage();
break;
case 'q': /* exit */
case '\033':
cleanup_and_exit();
}
glutPostRedisplay();
}
static void
raster_special(int key, int x, int y)
{
(void) x;
(void) y;
switch (key) {
case GLUT_KEY_PAGE_UP: /* previous logical image */
if (TIFFCurrentDirectory(tif) > 0) {
if (TIFFSetDirectory(tif,
TIFFCurrentDirectory(tif)-1)) {
initImage();
setWindowSize();
}
} else {
TIFFRGBAImageEnd(&img);
prevImage();
initImage();
setWindowSize();
}
break;
case GLUT_KEY_PAGE_DOWN: /* next logical image */
if (!TIFFLastDirectory(tif)) {
if (TIFFReadDirectory(tif)) {
initImage();
setWindowSize();
}
} else {
TIFFRGBAImageEnd(&img);
nextImage();
initImage();
setWindowSize();
}
break;
case GLUT_KEY_HOME: /* 1st image in current file */
if (TIFFSetDirectory(tif, 0)) {
TIFFRGBAImageEnd(&img);
initImage();
setWindowSize();
}
break;
case GLUT_KEY_END: /* last image in current file */
TIFFRGBAImageEnd(&img);
while (!TIFFLastDirectory(tif))
TIFFReadDirectory(tif);
initImage();
setWindowSize();
break;
}
glutPostRedisplay();
}
/* GLUT framework on MacOS X produces deprecation warnings */
# if defined(__GNUC__) && defined(__APPLE__)
# pragma GCC diagnostic pop
# endif
char* stuff[] = {
"usage: tiffgt [options] file.tif",
"where options are:",
" -c use colormap visual",
" -d dirnum set initial directory (default is 0)",
" -e enable display of TIFF error messages",
" -l force lsb-to-msb FillOrder",
" -m force msb-to-lsb FillOrder",
" -o offset set initial directory offset",
" -p photo override photometric interpretation",
" -r use fullcolor visual",
" -s stop decoding on first error (default is ignore errors)",
" -v enable verbose mode",
" -w enable display of TIFF warning messages",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
static uint16
photoArg(const char* arg)
{
if (strcmp(arg, "miniswhite") == 0)
return (PHOTOMETRIC_MINISWHITE);
else if (strcmp(arg, "minisblack") == 0)
return (PHOTOMETRIC_MINISBLACK);
else if (strcmp(arg, "rgb") == 0)
return (PHOTOMETRIC_RGB);
else if (strcmp(arg, "palette") == 0)
return (PHOTOMETRIC_PALETTE);
else if (strcmp(arg, "mask") == 0)
return (PHOTOMETRIC_MASK);
else if (strcmp(arg, "separated") == 0)
return (PHOTOMETRIC_SEPARATED);
else if (strcmp(arg, "ycbcr") == 0)
return (PHOTOMETRIC_YCBCR);
else if (strcmp(arg, "cielab") == 0)
return (PHOTOMETRIC_CIELAB);
else if (strcmp(arg, "logl") == 0)
return (PHOTOMETRIC_LOGL);
else if (strcmp(arg, "logluv") == 0)
return (PHOTOMETRIC_LOGLUV);
else
return ((uint16) -1);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,488 @@
/* $Id: tiffinfo.c,v 1.26 2016-12-03 14:18:49 erouault Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffiop.h"
static TIFFErrorHandler old_error_handler = 0;
static int status = 0; /* exit status */
static int showdata = 0; /* show data */
static int rawdata = 0; /* show raw/decoded data */
static int showwords = 0; /* show data as bytes/words */
static int readdata = 0; /* read data in file */
static int stoponerr = 1; /* stop on first read error */
static void usage(void);
static void tiffinfo(TIFF*, uint16, long, int);
static void
PrivateErrorHandler(const char* module, const char* fmt, va_list ap)
{
if (old_error_handler)
(*old_error_handler)(module,fmt,ap);
status = 1;
}
int
main(int argc, char* argv[])
{
int dirnum = -1, multiplefiles, c;
uint16 order = 0;
TIFF* tif;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
long flags = 0;
uint64 diroff = 0;
int chopstrips = 0; /* disable strip chopping */
while ((c = getopt(argc, argv, "f:o:cdDSjilmrsvwz0123456789")) != -1)
switch (c) {
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
dirnum = atoi(&argv[optind-1][1]);
break;
case 'd':
showdata++;
/* fall thru... */
case 'D':
readdata++;
break;
case 'c':
flags |= TIFFPRINT_COLORMAP | TIFFPRINT_CURVES;
break;
case 'f': /* fill order */
if (streq(optarg, "lsb2msb"))
order = FILLORDER_LSB2MSB;
else if (streq(optarg, "msb2lsb"))
order = FILLORDER_MSB2LSB;
else
usage();
break;
case 'i':
stoponerr = 0;
break;
case 'o':
diroff = strtoul(optarg, NULL, 0);
break;
case 'j':
flags |= TIFFPRINT_JPEGQTABLES |
TIFFPRINT_JPEGACTABLES |
TIFFPRINT_JPEGDCTABLES;
break;
case 'r':
rawdata = 1;
break;
case 's':
flags |= TIFFPRINT_STRIPS;
break;
case 'w':
showwords = 1;
break;
case 'z':
chopstrips = 1;
break;
case '?':
usage();
/*NOTREACHED*/
}
if (optind >= argc)
usage();
old_error_handler = TIFFSetErrorHandler(PrivateErrorHandler);
multiplefiles = (argc - optind > 1);
for (; optind < argc; optind++) {
if (multiplefiles)
printf("%s:\n", argv[optind]);
tif = TIFFOpen(argv[optind], chopstrips ? "rC" : "rc");
if (tif != NULL) {
if (dirnum != -1) {
if (TIFFSetDirectory(tif, (tdir_t) dirnum))
tiffinfo(tif, order, flags, 1);
} else if (diroff != 0) {
if (TIFFSetSubDirectory(tif, diroff))
tiffinfo(tif, order, flags, 1);
} else {
do {
toff_t offset=0;
tiffinfo(tif, order, flags, 1);
if (TIFFGetField(tif, TIFFTAG_EXIFIFD,
&offset)) {
if (TIFFReadEXIFDirectory(tif, offset)) {
tiffinfo(tif, order, flags, 0);
}
}
} while (TIFFReadDirectory(tif));
}
TIFFClose(tif);
}
}
return (status);
}
char* stuff[] = {
"usage: tiffinfo [options] input...",
"where options are:",
" -D read data",
" -i ignore read errors",
" -c display data for grey/color response curve or colormap",
" -d display raw/decoded image data",
" -f lsb2msb force lsb-to-msb FillOrder for input",
" -f msb2lsb force msb-to-lsb FillOrder for input",
" -j show JPEG tables",
" -o offset set initial directory offset",
" -r read/display raw image data instead of decoded data",
" -s display strip offsets and byte counts",
" -w display raw data in words rather than bytes",
" -z enable strip chopping",
" -# set initial directory (first directory is # 0)",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
static void
ShowStrip(tstrip_t strip, unsigned char* pp, uint32 nrow, tsize_t scanline)
{
register tsize_t cc;
printf("Strip %lu:\n", (unsigned long) strip);
while (nrow-- > 0) {
for (cc = 0; cc < scanline; cc++) {
printf(" %02x", *pp++);
if (((cc+1) % 24) == 0)
putchar('\n');
}
putchar('\n');
}
}
void
TIFFReadContigStripData(TIFF* tif)
{
unsigned char *buf;
tsize_t scanline = TIFFScanlineSize(tif);
buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
if (buf) {
uint32 row, h=0;
uint32 rowsperstrip = (uint32)-1;
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
for (row = 0; row < h; row += rowsperstrip) {
uint32 nrow = (row+rowsperstrip > h ?
h-row : rowsperstrip);
tstrip_t strip = TIFFComputeStrip(tif, row, 0);
if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) {
if (stoponerr)
break;
} else if (showdata)
ShowStrip(strip, buf, nrow, scanline);
}
_TIFFfree(buf);
}
}
void
TIFFReadSeparateStripData(TIFF* tif)
{
unsigned char *buf;
tsize_t scanline = TIFFScanlineSize(tif);
buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
if (buf) {
uint32 row, h=0;
uint32 rowsperstrip = (uint32)-1;
tsample_t s, samplesperpixel=0;
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
for (row = 0; row < h; row += rowsperstrip) {
for (s = 0; s < samplesperpixel; s++) {
uint32 nrow = (row+rowsperstrip > h ?
h-row : rowsperstrip);
tstrip_t strip = TIFFComputeStrip(tif, row, s);
if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) {
if (stoponerr)
break;
} else if (showdata)
ShowStrip(strip, buf, nrow, scanline);
}
}
_TIFFfree(buf);
}
}
static void
ShowTile(uint32 row, uint32 col, tsample_t sample,
unsigned char* pp, uint32 nrow, tsize_t rowsize)
{
uint32 cc;
printf("Tile (%lu,%lu", (unsigned long) row, (unsigned long) col);
if (sample != (tsample_t) -1)
printf(",%u", sample);
printf("):\n");
while (nrow-- > 0) {
for (cc = 0; cc < (uint32) rowsize; cc++) {
printf(" %02x", *pp++);
if (((cc+1) % 24) == 0)
putchar('\n');
}
putchar('\n');
}
}
void
TIFFReadContigTileData(TIFF* tif)
{
unsigned char *buf;
tmsize_t rowsize = TIFFTileRowSize(tif);
tmsize_t tilesize = TIFFTileSize(tif);
buf = (unsigned char *)_TIFFmalloc(tilesize);
if (buf) {
uint32 tw=0, th=0, w=0, h=0;
uint32 row, col;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
if ( rowsize == 0 || th > (size_t) (tilesize / rowsize) )
{
fprintf(stderr, "Cannot display data: th * rowsize > tilesize\n");
_TIFFfree(buf);
return;
}
for (row = 0; row < h; row += th) {
for (col = 0; col < w; col += tw) {
if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0) {
if (stoponerr)
break;
} else if (showdata)
ShowTile(row, col, (tsample_t) -1, buf, th, rowsize);
}
}
_TIFFfree(buf);
}
}
void
TIFFReadSeparateTileData(TIFF* tif)
{
unsigned char *buf;
tmsize_t rowsize = TIFFTileRowSize(tif);
tmsize_t tilesize = TIFFTileSize(tif);
buf = (unsigned char *)_TIFFmalloc(tilesize);
if (buf) {
uint32 tw=0, th=0, w=0, h=0;
uint32 row, col;
tsample_t s, samplesperpixel=0;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
if ( rowsize == 0 || th > (size_t) (tilesize / rowsize) )
{
fprintf(stderr, "Cannot display data: th * rowsize > tilesize\n");
_TIFFfree(buf);
return;
}
for (row = 0; row < h; row += th) {
for (col = 0; col < w; col += tw) {
for (s = 0; s < samplesperpixel; s++) {
if (TIFFReadTile(tif, buf, col, row, 0, s) < 0) {
if (stoponerr)
break;
} else if (showdata)
ShowTile(row, col, s, buf, th, rowsize);
}
}
}
_TIFFfree(buf);
}
}
void
TIFFReadData(TIFF* tif)
{
uint16 config = PLANARCONFIG_CONTIG;
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config);
if (TIFFIsTiled(tif)) {
if (config == PLANARCONFIG_CONTIG)
TIFFReadContigTileData(tif);
else
TIFFReadSeparateTileData(tif);
} else {
if (config == PLANARCONFIG_CONTIG)
TIFFReadContigStripData(tif);
else
TIFFReadSeparateStripData(tif);
}
}
static void
ShowRawBytes(unsigned char* pp, uint32 n)
{
uint32 i;
for (i = 0; i < n; i++) {
printf(" %02x", *pp++);
if (((i+1) % 24) == 0)
printf("\n ");
}
putchar('\n');
}
static void
ShowRawWords(uint16* pp, uint32 n)
{
uint32 i;
for (i = 0; i < n; i++) {
printf(" %04x", *pp++);
if (((i+1) % 15) == 0)
printf("\n ");
}
putchar('\n');
}
void
TIFFReadRawData(TIFF* tif, int bitrev)
{
tstrip_t nstrips = TIFFNumberOfStrips(tif);
const char* what = TIFFIsTiled(tif) ? "Tile" : "Strip";
uint64* stripbc=NULL;
TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc);
if (stripbc != NULL && nstrips > 0) {
uint32 bufsize = (uint32) stripbc[0];
tdata_t buf = _TIFFmalloc(bufsize);
tstrip_t s;
for (s = 0; s < nstrips; s++) {
if (stripbc[s] > bufsize) {
buf = _TIFFrealloc(buf, (tmsize_t)stripbc[s]);
bufsize = (uint32) stripbc[s];
}
if (buf == NULL) {
fprintf(stderr,
"Cannot allocate buffer to read strip %lu\n",
(unsigned long) s);
break;
}
if (TIFFReadRawStrip(tif, s, buf, (tmsize_t) stripbc[s]) < 0) {
fprintf(stderr, "Error reading strip %lu\n",
(unsigned long) s);
if (stoponerr)
break;
} else if (showdata) {
if (bitrev) {
TIFFReverseBits(buf, (tmsize_t)stripbc[s]);
printf("%s %lu: (bit reversed)\n ",
what, (unsigned long) s);
} else
printf("%s %lu:\n ", what,
(unsigned long) s);
if (showwords)
ShowRawWords((uint16*) buf, (uint32) stripbc[s]>>1);
else
ShowRawBytes((unsigned char*) buf, (uint32) stripbc[s]);
}
}
if (buf != NULL)
_TIFFfree(buf);
}
}
static void
tiffinfo(TIFF* tif, uint16 order, long flags, int is_image)
{
TIFFPrintDirectory(tif, stdout, flags);
if (!readdata || !is_image)
return;
if (rawdata) {
if (order) {
uint16 o;
TIFFGetFieldDefaulted(tif,
TIFFTAG_FILLORDER, &o);
TIFFReadRawData(tif, o != order);
} else
TIFFReadRawData(tif, 0);
} else {
if (order)
TIFFSetField(tif, TIFFTAG_FILLORDER, order);
TIFFReadData(tif);
}
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,918 @@
/* $Id: tiffmedian.c,v 1.13 2015-06-21 01:09:11 bfriesen Exp $ */
/*
* Apply median cut on an image.
*
* tiffmedian [-c n] [-f] input output
* -C n - set colortable size. Default is 256.
* -f - use Floyd-Steinberg dithering.
* -c lzw - compress output with LZW
* -c none - use no compression on output
* -c packbits - use packbits compression on output
* -r n - create output with n rows/strip of data
* (by default the compression scheme and rows/strip are taken
* from the input file)
*
* Notes:
*
* [1] Floyd-Steinberg dither:
* I should point out that the actual fractions we used were, assuming
* you are at X, moving left to right:
*
* X 7/16
* 3/16 5/16 1/16
*
* Note that the error goes to four neighbors, not three. I think this
* will probably do better (at least for black and white) than the
* 3/8-3/8-1/4 distribution, at the cost of greater processing. I have
* seen the 3/8-3/8-1/4 distribution described as "our" algorithm before,
* but I have no idea who the credit really belongs to.
* Also, I should add that if you do zig-zag scanning (see my immediately
* previous message), it is sufficient (but not quite as good) to send
* half the error one pixel ahead (e.g. to the right on lines you scan
* left to right), and half one pixel straight down. Again, this is for
* black and white; I've not tried it with color.
* --
* Lou Steinberg
*
* [2] Color Image Quantization for Frame Buffer Display, Paul Heckbert,
* Siggraph '82 proceedings, pp. 297-307
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef NEED_LIBPORT
# include "libport.h"
#endif
#include "tiffio.h"
#define MAX_CMAP_SIZE 256
#define streq(a,b) (strcmp(a,b) == 0)
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
#define COLOR_DEPTH 8
#define MAX_COLOR 256
#define B_DEPTH 5 /* # bits/pixel to use */
#define B_LEN (1L<<B_DEPTH)
#define C_DEPTH 2
#define C_LEN (1L<<C_DEPTH) /* # cells/color to use */
#define COLOR_SHIFT (COLOR_DEPTH-B_DEPTH)
typedef struct colorbox {
struct colorbox *next, *prev;
int rmin, rmax;
int gmin, gmax;
int bmin, bmax;
uint32 total;
} Colorbox;
typedef struct {
int num_ents;
int entries[MAX_CMAP_SIZE][2];
} C_cell;
uint16 rm[MAX_CMAP_SIZE], gm[MAX_CMAP_SIZE], bm[MAX_CMAP_SIZE];
int num_colors;
uint32 histogram[B_LEN][B_LEN][B_LEN];
Colorbox *freeboxes;
Colorbox *usedboxes;
C_cell **ColorCells;
TIFF *in, *out;
uint32 rowsperstrip = (uint32) -1;
uint16 compression = (uint16) -1;
uint16 bitspersample = 1;
uint16 samplesperpixel;
uint32 imagewidth;
uint32 imagelength;
uint16 predictor = 0;
static void get_histogram(TIFF*, Colorbox*);
static void splitbox(Colorbox*);
static void shrinkbox(Colorbox*);
static void map_colortable(void);
static void quant(TIFF*, TIFF*);
static void quant_fsdither(TIFF*, TIFF*);
static Colorbox* largest_box(void);
static void usage(void);
static int processCompressOptions(char*);
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
int
main(int argc, char* argv[])
{
int i, dither = 0;
uint16 shortv, config, photometric;
Colorbox *box_list, *ptr;
float floatv;
uint32 longv;
int c;
#if !HAVE_DECL_OPTARG
extern int optind;
extern char* optarg;
#endif
num_colors = MAX_CMAP_SIZE;
while ((c = getopt(argc, argv, "c:C:r:f")) != -1)
switch (c) {
case 'c': /* compression scheme */
if (!processCompressOptions(optarg))
usage();
break;
case 'C': /* set colormap size */
num_colors = atoi(optarg);
if (num_colors > MAX_CMAP_SIZE) {
fprintf(stderr,
"-c: colormap too big, max %d\n",
MAX_CMAP_SIZE);
usage();
}
break;
case 'f': /* dither */
dither = 1;
break;
case 'r': /* rows/strip */
rowsperstrip = atoi(optarg);
break;
case '?':
usage();
/*NOTREACHED*/
}
if (argc - optind != 2)
usage();
in = TIFFOpen(argv[optind], "r");
if (in == NULL)
return (-1);
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth);
TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength);
TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
if (bitspersample != 8 && bitspersample != 16) {
fprintf(stderr, "%s: Image must have at least 8-bits/sample\n",
argv[optind]);
return (-3);
}
if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) ||
photometric != PHOTOMETRIC_RGB || samplesperpixel < 3) {
fprintf(stderr, "%s: Image must have RGB data\n", argv[optind]);
return (-4);
}
TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config);
if (config != PLANARCONFIG_CONTIG) {
fprintf(stderr, "%s: Can only handle contiguous data packing\n",
argv[optind]);
return (-5);
}
/*
* STEP 1: create empty boxes
*/
usedboxes = NULL;
box_list = freeboxes = (Colorbox *)_TIFFmalloc(num_colors*sizeof (Colorbox));
freeboxes[0].next = &freeboxes[1];
freeboxes[0].prev = NULL;
for (i = 1; i < num_colors-1; ++i) {
freeboxes[i].next = &freeboxes[i+1];
freeboxes[i].prev = &freeboxes[i-1];
}
freeboxes[num_colors-1].next = NULL;
freeboxes[num_colors-1].prev = &freeboxes[num_colors-2];
/*
* STEP 2: get histogram, initialize first box
*/
ptr = freeboxes;
freeboxes = ptr->next;
if (freeboxes)
freeboxes->prev = NULL;
ptr->next = usedboxes;
usedboxes = ptr;
if (ptr->next)
ptr->next->prev = ptr;
get_histogram(in, ptr);
/*
* STEP 3: continually subdivide boxes until no more free
* boxes remain or until all colors assigned.
*/
while (freeboxes != NULL) {
ptr = largest_box();
if (ptr != NULL)
splitbox(ptr);
else
freeboxes = NULL;
}
/*
* STEP 4: assign colors to all boxes
*/
for (i = 0, ptr = usedboxes; ptr != NULL; ++i, ptr = ptr->next) {
rm[i] = ((ptr->rmin + ptr->rmax) << COLOR_SHIFT) / 2;
gm[i] = ((ptr->gmin + ptr->gmax) << COLOR_SHIFT) / 2;
bm[i] = ((ptr->bmin + ptr->bmax) << COLOR_SHIFT) / 2;
}
/* We're done with the boxes now */
_TIFFfree(box_list);
freeboxes = usedboxes = NULL;
/*
* STEP 5: scan histogram and map all values to closest color
*/
/* 5a: create cell list as described in Heckbert[2] */
ColorCells = (C_cell **)_TIFFmalloc(C_LEN*C_LEN*C_LEN*sizeof (C_cell*));
_TIFFmemset(ColorCells, 0, C_LEN*C_LEN*C_LEN*sizeof (C_cell*));
/* 5b: create mapping from truncated pixel space to color
table entries */
map_colortable();
/*
* STEP 6: scan image, match input values to table entries
*/
out = TIFFOpen(argv[optind+1], "w");
if (out == NULL)
return (-2);
CopyField(TIFFTAG_SUBFILETYPE, longv);
CopyField(TIFFTAG_IMAGEWIDTH, longv);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, (short)COLOR_DEPTH);
if (compression != (uint16)-1) {
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
switch (compression) {
case COMPRESSION_LZW:
case COMPRESSION_DEFLATE:
if (predictor != 0)
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
break;
}
} else
CopyField(TIFFTAG_COMPRESSION, compression);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, (short)PHOTOMETRIC_PALETTE);
CopyField(TIFFTAG_ORIENTATION, shortv);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, (short)1);
CopyField(TIFFTAG_PLANARCONFIG, shortv);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(out, rowsperstrip));
CopyField(TIFFTAG_MINSAMPLEVALUE, shortv);
CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv);
CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
CopyField(TIFFTAG_XRESOLUTION, floatv);
CopyField(TIFFTAG_YRESOLUTION, floatv);
CopyField(TIFFTAG_XPOSITION, floatv);
CopyField(TIFFTAG_YPOSITION, floatv);
if (dither)
quant_fsdither(in, out);
else
quant(in, out);
/*
* Scale colormap to TIFF-required 16-bit values.
*/
#define SCALE(x) (((x)*((1L<<16)-1))/255)
for (i = 0; i < MAX_CMAP_SIZE; ++i) {
rm[i] = SCALE(rm[i]);
gm[i] = SCALE(gm[i]);
bm[i] = SCALE(bm[i]);
}
TIFFSetField(out, TIFFTAG_COLORMAP, rm, gm, bm);
(void) TIFFClose(out);
return (0);
}
static int
processCompressOptions(char* opt)
{
if (streq(opt, "none"))
compression = COMPRESSION_NONE;
else if (streq(opt, "packbits"))
compression = COMPRESSION_PACKBITS;
else if (strneq(opt, "lzw", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_LZW;
} else if (strneq(opt, "zip", 3)) {
char* cp = strchr(opt, ':');
if (cp)
predictor = atoi(cp+1);
compression = COMPRESSION_DEFLATE;
} else
return (0);
return (1);
}
char* stuff[] = {
"usage: tiffmedian [options] input.tif output.tif",
"where options are:",
" -r # make each strip have no more than # rows",
" -C # create a colormap with # entries",
" -f use Floyd-Steinberg dithering",
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
" -c zip[:opts] compress output with deflate encoding",
" -c packbits compress output with packbits encoding",
" -c none use no compression algorithm on output",
"",
"LZW and deflate options:",
" # set predictor value",
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
NULL
};
static void
usage(void)
{
char buf[BUFSIZ];
int i;
setbuf(stderr, buf);
fprintf(stderr, "%s\n\n", TIFFGetVersion());
for (i = 0; stuff[i] != NULL; i++)
fprintf(stderr, "%s\n", stuff[i]);
exit(-1);
}
static void
get_histogram(TIFF* in, Colorbox* box)
{
register unsigned char *inptr;
register int red, green, blue;
register uint32 j, i;
unsigned char *inputline;
inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
if (inputline == NULL) {
fprintf(stderr, "No space for scanline buffer\n");
exit(-1);
}
box->rmin = box->gmin = box->bmin = 999;
box->rmax = box->gmax = box->bmax = -1;
box->total = imagewidth * imagelength;
{ register uint32 *ptr = &histogram[0][0][0];
for (i = B_LEN*B_LEN*B_LEN; i-- > 0;)
*ptr++ = 0;
}
for (i = 0; i < imagelength; i++) {
if (TIFFReadScanline(in, inputline, i, 0) <= 0)
break;
inptr = inputline;
for (j = imagewidth; j-- > 0;) {
red = (*inptr++) & 0xff >> COLOR_SHIFT;
green = (*inptr++) & 0xff >> COLOR_SHIFT;
blue = (*inptr++) & 0xff >> COLOR_SHIFT;
if ((red | green | blue) >= B_LEN) {
fprintf(stderr,
"Logic error. "
"Histogram array overflow!\n");
exit(-6);
}
if (red < box->rmin)
box->rmin = red;
if (red > box->rmax)
box->rmax = red;
if (green < box->gmin)
box->gmin = green;
if (green > box->gmax)
box->gmax = green;
if (blue < box->bmin)
box->bmin = blue;
if (blue > box->bmax)
box->bmax = blue;
histogram[red][green][blue]++;
}
}
_TIFFfree(inputline);
}
static Colorbox *
largest_box(void)
{
register Colorbox *p, *b;
register uint32 size;
b = NULL;
size = 0;
for (p = usedboxes; p != NULL; p = p->next)
if ((p->rmax > p->rmin || p->gmax > p->gmin ||
p->bmax > p->bmin) && p->total > size)
size = (b = p)->total;
return (b);
}
static void
splitbox(Colorbox* ptr)
{
uint32 hist2[B_LEN];
int first=0, last=0;
register Colorbox *new;
register uint32 *iptr, *histp;
register int i, j;
register int ir,ig,ib;
register uint32 sum, sum1, sum2;
enum { RED, GREEN, BLUE } axis;
/*
* See which axis is the largest, do a histogram along that
* axis. Split at median point. Contract both new boxes to
* fit points and return
*/
i = ptr->rmax - ptr->rmin;
if (i >= ptr->gmax - ptr->gmin && i >= ptr->bmax - ptr->bmin)
axis = RED;
else if (ptr->gmax - ptr->gmin >= ptr->bmax - ptr->bmin)
axis = GREEN;
else
axis = BLUE;
/* get histogram along longest axis */
switch (axis) {
case RED:
histp = &hist2[ptr->rmin];
for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
*histp = 0;
for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
iptr = &histogram[ir][ig][ptr->bmin];
for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
*histp += *iptr++;
}
histp++;
}
first = ptr->rmin;
last = ptr->rmax;
break;
case GREEN:
histp = &hist2[ptr->gmin];
for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
*histp = 0;
for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
iptr = &histogram[ir][ig][ptr->bmin];
for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
*histp += *iptr++;
}
histp++;
}
first = ptr->gmin;
last = ptr->gmax;
break;
case BLUE:
histp = &hist2[ptr->bmin];
for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) {
*histp = 0;
for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
iptr = &histogram[ir][ptr->gmin][ib];
for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
*histp += *iptr;
iptr += B_LEN;
}
}
histp++;
}
first = ptr->bmin;
last = ptr->bmax;
break;
}
/* find median point */
sum2 = ptr->total / 2;
histp = &hist2[first];
sum = 0;
for (i = first; i <= last && (sum += *histp++) < sum2; ++i)
;
if (i == first)
i++;
/* Create new box, re-allocate points */
new = freeboxes;
freeboxes = new->next;
if (freeboxes)
freeboxes->prev = NULL;
if (usedboxes)
usedboxes->prev = new;
new->next = usedboxes;
usedboxes = new;
histp = &hist2[first];
for (sum1 = 0, j = first; j < i; j++)
sum1 += *histp++;
for (sum2 = 0, j = i; j <= last; j++)
sum2 += *histp++;
new->total = sum1;
ptr->total = sum2;
new->rmin = ptr->rmin;
new->rmax = ptr->rmax;
new->gmin = ptr->gmin;
new->gmax = ptr->gmax;
new->bmin = ptr->bmin;
new->bmax = ptr->bmax;
switch (axis) {
case RED:
new->rmax = i-1;
ptr->rmin = i;
break;
case GREEN:
new->gmax = i-1;
ptr->gmin = i;
break;
case BLUE:
new->bmax = i-1;
ptr->bmin = i;
break;
}
shrinkbox(new);
shrinkbox(ptr);
}
static void
shrinkbox(Colorbox* box)
{
register uint32 *histp;
register int ir, ig, ib;
if (box->rmax > box->rmin) {
for (ir = box->rmin; ir <= box->rmax; ++ir)
for (ig = box->gmin; ig <= box->gmax; ++ig) {
histp = &histogram[ir][ig][box->bmin];
for (ib = box->bmin; ib <= box->bmax; ++ib)
if (*histp++ != 0) {
box->rmin = ir;
goto have_rmin;
}
}
have_rmin:
if (box->rmax > box->rmin)
for (ir = box->rmax; ir >= box->rmin; --ir)
for (ig = box->gmin; ig <= box->gmax; ++ig) {
histp = &histogram[ir][ig][box->bmin];
ib = box->bmin;
for (; ib <= box->bmax; ++ib)
if (*histp++ != 0) {
box->rmax = ir;
goto have_rmax;
}
}
}
have_rmax:
if (box->gmax > box->gmin) {
for (ig = box->gmin; ig <= box->gmax; ++ig)
for (ir = box->rmin; ir <= box->rmax; ++ir) {
histp = &histogram[ir][ig][box->bmin];
for (ib = box->bmin; ib <= box->bmax; ++ib)
if (*histp++ != 0) {
box->gmin = ig;
goto have_gmin;
}
}
have_gmin:
if (box->gmax > box->gmin)
for (ig = box->gmax; ig >= box->gmin; --ig)
for (ir = box->rmin; ir <= box->rmax; ++ir) {
histp = &histogram[ir][ig][box->bmin];
ib = box->bmin;
for (; ib <= box->bmax; ++ib)
if (*histp++ != 0) {
box->gmax = ig;
goto have_gmax;
}
}
}
have_gmax:
if (box->bmax > box->bmin) {
for (ib = box->bmin; ib <= box->bmax; ++ib)
for (ir = box->rmin; ir <= box->rmax; ++ir) {
histp = &histogram[ir][box->gmin][ib];
for (ig = box->gmin; ig <= box->gmax; ++ig) {
if (*histp != 0) {
box->bmin = ib;
goto have_bmin;
}
histp += B_LEN;
}
}
have_bmin:
if (box->bmax > box->bmin)
for (ib = box->bmax; ib >= box->bmin; --ib)
for (ir = box->rmin; ir <= box->rmax; ++ir) {
histp = &histogram[ir][box->gmin][ib];
ig = box->gmin;
for (; ig <= box->gmax; ++ig) {
if (*histp != 0) {
box->bmax = ib;
goto have_bmax;
}
histp += B_LEN;
}
}
}
have_bmax:
;
}
static C_cell *
create_colorcell(int red, int green, int blue)
{
register int ir, ig, ib, i;
register C_cell *ptr;
int mindist, next_n;
register int tmp, dist, n;
ir = red >> (COLOR_DEPTH-C_DEPTH);
ig = green >> (COLOR_DEPTH-C_DEPTH);
ib = blue >> (COLOR_DEPTH-C_DEPTH);
ptr = (C_cell *)_TIFFmalloc(sizeof (C_cell));
*(ColorCells + ir*C_LEN*C_LEN + ig*C_LEN + ib) = ptr;
ptr->num_ents = 0;
/*
* Step 1: find all colors inside this cell, while we're at
* it, find distance of centermost point to furthest corner
*/
mindist = 99999999;
for (i = 0; i < num_colors; ++i) {
if (rm[i]>>(COLOR_DEPTH-C_DEPTH) != ir ||
gm[i]>>(COLOR_DEPTH-C_DEPTH) != ig ||
bm[i]>>(COLOR_DEPTH-C_DEPTH) != ib)
continue;
ptr->entries[ptr->num_ents][0] = i;
ptr->entries[ptr->num_ents][1] = 0;
++ptr->num_ents;
tmp = rm[i] - red;
if (tmp < (MAX_COLOR/C_LEN/2))
tmp = MAX_COLOR/C_LEN-1 - tmp;
dist = tmp*tmp;
tmp = gm[i] - green;
if (tmp < (MAX_COLOR/C_LEN/2))
tmp = MAX_COLOR/C_LEN-1 - tmp;
dist += tmp*tmp;
tmp = bm[i] - blue;
if (tmp < (MAX_COLOR/C_LEN/2))
tmp = MAX_COLOR/C_LEN-1 - tmp;
dist += tmp*tmp;
if (dist < mindist)
mindist = dist;
}
/*
* Step 3: find all points within that distance to cell.
*/
for (i = 0; i < num_colors; ++i) {
if (rm[i] >> (COLOR_DEPTH-C_DEPTH) == ir &&
gm[i] >> (COLOR_DEPTH-C_DEPTH) == ig &&
bm[i] >> (COLOR_DEPTH-C_DEPTH) == ib)
continue;
dist = 0;
if ((tmp = red - rm[i]) > 0 ||
(tmp = rm[i] - (red + MAX_COLOR/C_LEN-1)) > 0 )
dist += tmp*tmp;
if ((tmp = green - gm[i]) > 0 ||
(tmp = gm[i] - (green + MAX_COLOR/C_LEN-1)) > 0 )
dist += tmp*tmp;
if ((tmp = blue - bm[i]) > 0 ||
(tmp = bm[i] - (blue + MAX_COLOR/C_LEN-1)) > 0 )
dist += tmp*tmp;
if (dist < mindist) {
ptr->entries[ptr->num_ents][0] = i;
ptr->entries[ptr->num_ents][1] = dist;
++ptr->num_ents;
}
}
/*
* Sort color cells by distance, use cheap exchange sort
*/
for (n = ptr->num_ents - 1; n > 0; n = next_n) {
next_n = 0;
for (i = 0; i < n; ++i)
if (ptr->entries[i][1] > ptr->entries[i+1][1]) {
tmp = ptr->entries[i][0];
ptr->entries[i][0] = ptr->entries[i+1][0];
ptr->entries[i+1][0] = tmp;
tmp = ptr->entries[i][1];
ptr->entries[i][1] = ptr->entries[i+1][1];
ptr->entries[i+1][1] = tmp;
next_n = i;
}
}
return (ptr);
}
static void
map_colortable(void)
{
register uint32 *histp = &histogram[0][0][0];
register C_cell *cell;
register int j, tmp, d2, dist;
int ir, ig, ib, i;
for (ir = 0; ir < B_LEN; ++ir)
for (ig = 0; ig < B_LEN; ++ig)
for (ib = 0; ib < B_LEN; ++ib, histp++) {
if (*histp == 0) {
*histp = -1;
continue;
}
cell = *(ColorCells +
(((ir>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) +
((ig>>(B_DEPTH-C_DEPTH)) << C_DEPTH) +
(ib>>(B_DEPTH-C_DEPTH))));
if (cell == NULL )
cell = create_colorcell(
ir << COLOR_SHIFT,
ig << COLOR_SHIFT,
ib << COLOR_SHIFT);
dist = 9999999;
for (i = 0; i < cell->num_ents &&
dist > cell->entries[i][1]; ++i) {
j = cell->entries[i][0];
d2 = rm[j] - (ir << COLOR_SHIFT);
d2 *= d2;
tmp = gm[j] - (ig << COLOR_SHIFT);
d2 += tmp*tmp;
tmp = bm[j] - (ib << COLOR_SHIFT);
d2 += tmp*tmp;
if (d2 < dist) {
dist = d2;
*histp = j;
}
}
}
}
/*
* straight quantization. Each pixel is mapped to the colors
* closest to it. Color values are rounded to the nearest color
* table entry.
*/
static void
quant(TIFF* in, TIFF* out)
{
unsigned char *outline, *inputline;
register unsigned char *outptr, *inptr;
register uint32 i, j;
register int red, green, blue;
inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
outline = (unsigned char *)_TIFFmalloc(imagewidth);
for (i = 0; i < imagelength; i++) {
if (TIFFReadScanline(in, inputline, i, 0) <= 0)
break;
inptr = inputline;
outptr = outline;
for (j = 0; j < imagewidth; j++) {
red = *inptr++ >> COLOR_SHIFT;
green = *inptr++ >> COLOR_SHIFT;
blue = *inptr++ >> COLOR_SHIFT;
*outptr++ = (unsigned char)histogram[red][green][blue];
}
if (TIFFWriteScanline(out, outline, i, 0) < 0)
break;
}
_TIFFfree(inputline);
_TIFFfree(outline);
}
#define SWAP(type,a,b) { type p; p = a; a = b; b = p; }
#define GetInputLine(tif, row, bad) \
do { \
if (TIFFReadScanline(tif, inputline, row, 0) <= 0) \
bad; \
inptr = inputline; \
nextptr = nextline; \
for (j = 0; j < imagewidth; ++j) { \
*nextptr++ = *inptr++; \
*nextptr++ = *inptr++; \
*nextptr++ = *inptr++; \
} \
} while (0);
#define GetComponent(raw, cshift, c) \
do { \
cshift = raw; \
if (cshift < 0) \
cshift = 0; \
else if (cshift >= MAX_COLOR) \
cshift = MAX_COLOR-1; \
c = cshift; \
cshift >>= COLOR_SHIFT; \
} while (0);
static void
quant_fsdither(TIFF* in, TIFF* out)
{
unsigned char *outline, *inputline, *inptr;
short *thisline, *nextline;
register unsigned char *outptr;
register short *thisptr, *nextptr;
register uint32 i, j;
uint32 imax, jmax;
int lastline, lastpixel;
imax = imagelength - 1;
jmax = imagewidth - 1;
inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
thisline = (short *)_TIFFmalloc(imagewidth * 3 * sizeof (short));
nextline = (short *)_TIFFmalloc(imagewidth * 3 * sizeof (short));
outline = (unsigned char *) _TIFFmalloc(TIFFScanlineSize(out));
GetInputLine(in, 0, goto bad); /* get first line */
for (i = 1; i <= imagelength; ++i) {
SWAP(short *, thisline, nextline);
lastline = (i >= imax);
if (i <= imax)
GetInputLine(in, i, break);
thisptr = thisline;
nextptr = nextline;
outptr = outline;
for (j = 0; j < imagewidth; ++j) {
int red, green, blue;
register int oval, r2, g2, b2;
lastpixel = (j == jmax);
GetComponent(*thisptr++, r2, red);
GetComponent(*thisptr++, g2, green);
GetComponent(*thisptr++, b2, blue);
oval = histogram[r2][g2][b2];
if (oval == -1) {
int ci;
register int cj, tmp, d2, dist;
register C_cell *cell;
cell = *(ColorCells +
(((r2>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) +
((g2>>(B_DEPTH-C_DEPTH)) << C_DEPTH ) +
(b2>>(B_DEPTH-C_DEPTH))));
if (cell == NULL)
cell = create_colorcell(red,
green, blue);
dist = 9999999;
for (ci = 0; ci < cell->num_ents && dist > cell->entries[ci][1]; ++ci) {
cj = cell->entries[ci][0];
d2 = (rm[cj] >> COLOR_SHIFT) - r2;
d2 *= d2;
tmp = (gm[cj] >> COLOR_SHIFT) - g2;
d2 += tmp*tmp;
tmp = (bm[cj] >> COLOR_SHIFT) - b2;
d2 += tmp*tmp;
if (d2 < dist) {
dist = d2;
oval = cj;
}
}
histogram[r2][g2][b2] = oval;
}
*outptr++ = oval;
red -= rm[oval];
green -= gm[oval];
blue -= bm[oval];
if (!lastpixel) {
thisptr[0] += blue * 7 / 16;
thisptr[1] += green * 7 / 16;
thisptr[2] += red * 7 / 16;
}
if (!lastline) {
if (j != 0) {
nextptr[-3] += blue * 3 / 16;
nextptr[-2] += green * 3 / 16;
nextptr[-1] += red * 3 / 16;
}
nextptr[0] += blue * 5 / 16;
nextptr[1] += green * 5 / 16;
nextptr[2] += red * 5 / 16;
if (!lastpixel) {
nextptr[3] += blue / 16;
nextptr[4] += green / 16;
nextptr[5] += red / 16;
}
nextptr += 3;
}
}
if (TIFFWriteScanline(out, outline, i-1, 0) < 0)
break;
}
bad:
_TIFFfree(inputline);
_TIFFfree(thisline);
_TIFFfree(nextline);
_TIFFfree(outline);
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,356 @@
/******************************************************************************
* $Id: tiffset.c,v 1.19 2017-10-01 17:38:12 erouault Exp $
*
* Project: libtiff tools
* Purpose: Mainline for setting metadata in existing TIFF files.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 2000, Frank Warmerdam
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
******************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "tiffio.h"
static char* usageMsg[] = {
"usage: tiffset [options] filename",
"where options are:",
" -s <tagname> [count] <value>... set the tag value",
" -u <tagname> to unset the tag",
" -d <dirno> set the directory",
" -sd <diroff> set the subdirectory",
" -sf <tagname> <filename> read the tag value from file (for ASCII tags only)",
NULL
};
static void
usage(void)
{
int i;
for (i = 0; usageMsg[i]; i++)
fprintf(stderr, "%s\n", usageMsg[i]);
exit(-1);
}
static const TIFFField *
GetField(TIFF *tiff, const char *tagname)
{
const TIFFField *fip;
if( atoi(tagname) > 0 )
fip = TIFFFieldWithTag(tiff, (ttag_t)atoi(tagname));
else
fip = TIFFFieldWithName(tiff, tagname);
if (!fip) {
fprintf( stderr, "Field name \"%s\" is not recognised.\n", tagname );
return (TIFFField *)NULL;
}
return fip;
}
int
main(int argc, char* argv[])
{
TIFF *tiff;
int arg_index;
if (argc < 2)
usage();
tiff = TIFFOpen(argv[argc-1], "r+");
if (tiff == NULL)
return 2;
for( arg_index = 1; arg_index < argc-1; arg_index++ ) {
if (strcmp(argv[arg_index],"-d") == 0 && arg_index < argc-2) {
arg_index++;
if( TIFFSetDirectory(tiff, atoi(argv[arg_index]) ) != 1 )
{
fprintf( stderr, "Failed to set directory=%s\n", argv[arg_index] );
return 6;
}
arg_index++;
}
if (strcmp(argv[arg_index],"-sd") == 0 && arg_index < argc-2) {
arg_index++;
if( TIFFSetSubDirectory(tiff, atoi(argv[arg_index]) ) != 1 )
{
fprintf( stderr, "Failed to set sub directory=%s\n", argv[arg_index] );
return 7;
}
arg_index++;
}
/* Add unset option to tiffset -- Zach Baker (niquil@niquil.net) 11/14/2012 */
if (strcmp(argv[arg_index],"-u") == 0 && arg_index < argc-2) {
const TIFFField *fip;
const char *tagname;
arg_index++;
tagname = argv[arg_index];
fip = GetField(tiff, tagname);
if (!fip)
return 3;
if (TIFFUnsetField(tiff, TIFFFieldTag(fip)) != 1)
{
fprintf(stderr, "Failed to unset %s\n", TIFFFieldName(fip));
}
arg_index++;
} else if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) {
const TIFFField *fip;
const char *tagname;
arg_index++;
tagname = argv[arg_index];
fip = GetField(tiff, tagname);
if (!fip)
return 3;
arg_index++;
if (TIFFFieldDataType(fip) == TIFF_ASCII) {
if (TIFFSetField(tiff, TIFFFieldTag(fip), argv[arg_index]) != 1)
fprintf( stderr, "Failed to set %s=%s\n",
TIFFFieldName(fip), argv[arg_index] );
} else if (TIFFFieldWriteCount(fip) > 0
|| TIFFFieldWriteCount(fip) == TIFF_VARIABLE) {
int ret = 1;
short wc;
if (TIFFFieldWriteCount(fip) == TIFF_VARIABLE)
wc = atoi(argv[arg_index++]);
else
wc = TIFFFieldWriteCount(fip);
if (argc - arg_index < wc) {
fprintf( stderr,
"Number of tag values is not enough. "
"Expected %d values for %s tag, got %d\n",
wc, TIFFFieldName(fip), argc - arg_index);
return 4;
}
if (wc > 1 || TIFFFieldWriteCount(fip) == TIFF_VARIABLE) {
int i, size;
void *array;
switch (TIFFFieldDataType(fip)) {
/*
* XXX: We can't use TIFFDataWidth()
* to determine the space needed to store
* the value. For TIFF_RATIONAL values
* TIFFDataWidth() returns 8, but we use 4-byte
* float to represent rationals.
*/
case TIFF_BYTE:
case TIFF_ASCII:
case TIFF_SBYTE:
case TIFF_UNDEFINED:
default:
size = 1;
break;
case TIFF_SHORT:
case TIFF_SSHORT:
size = 2;
break;
case TIFF_LONG:
case TIFF_SLONG:
case TIFF_FLOAT:
case TIFF_IFD:
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
size = 4;
break;
case TIFF_DOUBLE:
size = 8;
break;
}
array = _TIFFmalloc(wc * size);
if (!array) {
fprintf(stderr, "No space for %s tag\n",
tagname);
return 4;
}
switch (TIFFFieldDataType(fip)) {
case TIFF_BYTE:
for (i = 0; i < wc; i++)
((uint8 *)array)[i] = atoi(argv[arg_index+i]);
break;
case TIFF_SHORT:
for (i = 0; i < wc; i++)
((uint16 *)array)[i] = atoi(argv[arg_index+i]);
break;
case TIFF_SBYTE:
for (i = 0; i < wc; i++)
((int8 *)array)[i] = atoi(argv[arg_index+i]);
break;
case TIFF_SSHORT:
for (i = 0; i < wc; i++)
((int16 *)array)[i] = atoi(argv[arg_index+i]);
break;
case TIFF_LONG:
for (i = 0; i < wc; i++)
((uint32 *)array)[i] = atol(argv[arg_index+i]);
break;
case TIFF_SLONG:
case TIFF_IFD:
for (i = 0; i < wc; i++)
((uint32 *)array)[i] = atol(argv[arg_index+i]);
break;
case TIFF_DOUBLE:
for (i = 0; i < wc; i++)
((double *)array)[i] = atof(argv[arg_index+i]);
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
case TIFF_FLOAT:
for (i = 0; i < wc; i++)
((float *)array)[i] = (float)atof(argv[arg_index+i]);
break;
default:
break;
}
if (TIFFFieldPassCount(fip)) {
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
wc, array);
} else if (TIFFFieldTag(fip) == TIFFTAG_PAGENUMBER
|| TIFFFieldTag(fip) == TIFFTAG_HALFTONEHINTS
|| TIFFFieldTag(fip) == TIFFTAG_YCBCRSUBSAMPLING
|| TIFFFieldTag(fip) == TIFFTAG_DOTRANGE) {
if (TIFFFieldDataType(fip) == TIFF_BYTE) {
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
((uint8 *)array)[0], ((uint8 *)array)[1]);
} else if (TIFFFieldDataType(fip) == TIFF_SHORT) {
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
((uint16 *)array)[0], ((uint16 *)array)[1]);
}
} else {
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
array);
}
_TIFFfree(array);
} else {
switch (TIFFFieldDataType(fip)) {
case TIFF_BYTE:
case TIFF_SHORT:
case TIFF_SBYTE:
case TIFF_SSHORT:
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
atoi(argv[arg_index++]));
break;
case TIFF_LONG:
case TIFF_SLONG:
case TIFF_IFD:
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
atol(argv[arg_index++]));
break;
case TIFF_DOUBLE:
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
atof(argv[arg_index++]));
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
case TIFF_FLOAT:
ret = TIFFSetField(tiff, TIFFFieldTag(fip),
(float)atof(argv[arg_index++]));
break;
default:
break;
}
}
if (ret != 1)
fprintf(stderr, "Failed to set %s\n", TIFFFieldName(fip));
arg_index += wc;
}
} else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) {
FILE *fp;
const TIFFField *fip;
char *text;
size_t len;
arg_index++;
fip = GetField(tiff, argv[arg_index]);
if (!fip)
return 3;
if (TIFFFieldDataType(fip) != TIFF_ASCII) {
fprintf( stderr,
"Only ASCII tags can be set from file. "
"%s is not ASCII tag.\n", TIFFFieldName(fip) );
return 5;
}
arg_index++;
fp = fopen( argv[arg_index], "rt" );
if(fp == NULL) {
perror( argv[arg_index] );
continue;
}
text = (char *) malloc(1000000);
len = fread( text, 1, 999999, fp );
text[len] = '\0';
fclose( fp );
if(TIFFSetField( tiff, TIFFFieldTag(fip), text ) != 1) {
fprintf(stderr, "Failed to set %s from file %s\n",
TIFFFieldName(fip), argv[arg_index]);
}
_TIFFfree( text );
arg_index++;
} else {
fprintf(stderr, "Unrecognised option: %s\n",
argv[arg_index]);
usage();
}
}
TIFFRewriteDirectory(tiff);
TIFFClose(tiff);
return 0;
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/

View File

@ -0,0 +1,305 @@
/* $Id: tiffsplit.c,v 1.23 2015-05-28 13:10:26 bfriesen Exp $ */
/*
* Copyright (c) 1992-1997 Sam Leffler
* Copyright (c) 1992-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "tif_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tiffio.h"
#ifndef HAVE_GETOPT
extern int getopt(int, char**, char*);
#endif
#define CopyField(tag, v) \
if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
#define CopyField2(tag, v1, v2) \
if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
#define CopyField3(tag, v1, v2, v3) \
if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
#define PATH_LENGTH 8192
static const char TIFF_SUFFIX[] = ".tif";
static char fname[PATH_LENGTH];
static int tiffcp(TIFF*, TIFF*);
static void newfilename(void);
static int cpStrips(TIFF*, TIFF*);
static int cpTiles(TIFF*, TIFF*);
int
main(int argc, char* argv[])
{
TIFF *in, *out;
if (argc < 2) {
fprintf(stderr, "%s\n\n", TIFFGetVersion());
fprintf(stderr, "usage: tiffsplit input.tif [prefix]\n");
return (-3);
}
if (argc > 2) {
strncpy(fname, argv[2], sizeof(fname));
fname[sizeof(fname) - 1] = '\0';
}
in = TIFFOpen(argv[1], "r");
if (in != NULL) {
do {
size_t path_len;
char *path;
newfilename();
path_len = strlen(fname) + sizeof(TIFF_SUFFIX);
path = (char *) _TIFFmalloc(path_len);
strncpy(path, fname, path_len);
path[path_len - 1] = '\0';
strncat(path, TIFF_SUFFIX, path_len - strlen(path) - 1);
out = TIFFOpen(path, TIFFIsBigEndian(in)?"wb":"wl");
_TIFFfree(path);
if (out == NULL)
return (-2);
if (!tiffcp(in, out))
return (-1);
TIFFClose(out);
} while (TIFFReadDirectory(in));
(void) TIFFClose(in);
}
return (0);
}
static void
newfilename(void)
{
static int first = 1;
static long lastTurn;
static long fnum;
static short defname;
static char *fpnt;
if (first) {
if (fname[0]) {
fpnt = fname + strlen(fname);
defname = 0;
} else {
fname[0] = 'x';
fpnt = fname + 1;
defname = 1;
}
first = 0;
}
#define MAXFILES 17576
if (fnum == MAXFILES) {
if (!defname || fname[0] == 'z') {
fprintf(stderr, "tiffsplit: too many files.\n");
exit(1);
}
fname[0]++;
fnum = 0;
}
if (fnum % 676 == 0) {
if (fnum != 0) {
/*
* advance to next letter every 676 pages
* condition for 'z'++ will be covered above
*/
fpnt[0]++;
} else {
/*
* set to 'a' if we are on the very first file
*/
fpnt[0] = 'a';
}
/*
* set the value of the last turning point
*/
lastTurn = fnum;
}
/*
* start from 0 every 676 times (provided by lastTurn)
* this keeps us within a-z boundaries
*/
fpnt[1] = (char)((fnum - lastTurn) / 26) + 'a';
/*
* cycle last letter every file, from a-z, then repeat
*/
fpnt[2] = (char)(fnum % 26) + 'a';
fnum++;
}
static int
tiffcp(TIFF* in, TIFF* out)
{
uint16 bitspersample, samplesperpixel, compression, shortv, *shortav;
uint32 w, l;
float floatv;
char *stringv;
uint32 longv;
CopyField(TIFFTAG_SUBFILETYPE, longv);
CopyField(TIFFTAG_TILEWIDTH, w);
CopyField(TIFFTAG_TILELENGTH, l);
CopyField(TIFFTAG_IMAGEWIDTH, w);
CopyField(TIFFTAG_IMAGELENGTH, l);
CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
CopyField(TIFFTAG_COMPRESSION, compression);
if (compression == COMPRESSION_JPEG) {
uint32 count = 0;
void *table = NULL;
if (TIFFGetField(in, TIFFTAG_JPEGTABLES, &count, &table)
&& count > 0 && table) {
TIFFSetField(out, TIFFTAG_JPEGTABLES, count, table);
}
}
CopyField(TIFFTAG_PHOTOMETRIC, shortv);
CopyField(TIFFTAG_PREDICTOR, shortv);
CopyField(TIFFTAG_THRESHHOLDING, shortv);
CopyField(TIFFTAG_FILLORDER, shortv);
CopyField(TIFFTAG_ORIENTATION, shortv);
CopyField(TIFFTAG_MINSAMPLEVALUE, shortv);
CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv);
CopyField(TIFFTAG_XRESOLUTION, floatv);
CopyField(TIFFTAG_YRESOLUTION, floatv);
CopyField(TIFFTAG_GROUP3OPTIONS, longv);
CopyField(TIFFTAG_GROUP4OPTIONS, longv);
CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
CopyField(TIFFTAG_PLANARCONFIG, shortv);
CopyField(TIFFTAG_ROWSPERSTRIP, longv);
CopyField(TIFFTAG_XPOSITION, floatv);
CopyField(TIFFTAG_YPOSITION, floatv);
CopyField(TIFFTAG_IMAGEDEPTH, longv);
CopyField(TIFFTAG_TILEDEPTH, longv);
CopyField(TIFFTAG_SAMPLEFORMAT, shortv);
CopyField2(TIFFTAG_EXTRASAMPLES, shortv, shortav);
{ uint16 *red, *green, *blue;
CopyField3(TIFFTAG_COLORMAP, red, green, blue);
}
{ uint16 shortv2;
CopyField2(TIFFTAG_PAGENUMBER, shortv, shortv2);
}
CopyField(TIFFTAG_ARTIST, stringv);
CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv);
CopyField(TIFFTAG_MAKE, stringv);
CopyField(TIFFTAG_MODEL, stringv);
CopyField(TIFFTAG_SOFTWARE, stringv);
CopyField(TIFFTAG_DATETIME, stringv);
CopyField(TIFFTAG_HOSTCOMPUTER, stringv);
CopyField(TIFFTAG_PAGENAME, stringv);
CopyField(TIFFTAG_DOCUMENTNAME, stringv);
CopyField(TIFFTAG_BADFAXLINES, longv);
CopyField(TIFFTAG_CLEANFAXDATA, longv);
CopyField(TIFFTAG_CONSECUTIVEBADFAXLINES, longv);
CopyField(TIFFTAG_FAXRECVPARAMS, longv);
CopyField(TIFFTAG_FAXRECVTIME, longv);
CopyField(TIFFTAG_FAXSUBADDRESS, stringv);
CopyField(TIFFTAG_FAXDCS, stringv);
if (TIFFIsTiled(in))
return (cpTiles(in, out));
else
return (cpStrips(in, out));
}
static int
cpStrips(TIFF* in, TIFF* out)
{
tmsize_t bufsize = TIFFStripSize(in);
unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
if (buf) {
tstrip_t s, ns = TIFFNumberOfStrips(in);
uint64 *bytecounts;
if (!TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts)) {
fprintf(stderr, "tiffsplit: strip byte counts are missing\n");
_TIFFfree(buf);
return (0);
}
for (s = 0; s < ns; s++) {
if (bytecounts[s] > (uint64)bufsize) {
buf = (unsigned char *)_TIFFrealloc(buf, (tmsize_t)bytecounts[s]);
if (!buf)
return (0);
bufsize = (tmsize_t)bytecounts[s];
}
if (TIFFReadRawStrip(in, s, buf, (tmsize_t)bytecounts[s]) < 0 ||
TIFFWriteRawStrip(out, s, buf, (tmsize_t)bytecounts[s]) < 0) {
_TIFFfree(buf);
return (0);
}
}
_TIFFfree(buf);
return (1);
}
return (0);
}
static int
cpTiles(TIFF* in, TIFF* out)
{
tmsize_t bufsize = TIFFTileSize(in);
unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
if (buf) {
ttile_t t, nt = TIFFNumberOfTiles(in);
uint64 *bytecounts;
if (!TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts)) {
fprintf(stderr, "tiffsplit: tile byte counts are missing\n");
_TIFFfree(buf);
return (0);
}
for (t = 0; t < nt; t++) {
if (bytecounts[t] > (uint64) bufsize) {
buf = (unsigned char *)_TIFFrealloc(buf, (tmsize_t)bytecounts[t]);
if (!buf)
return (0);
bufsize = (tmsize_t)bytecounts[t];
}
if (TIFFReadRawTile(in, t, buf, (tmsize_t)bytecounts[t]) < 0 ||
TIFFWriteRawTile(out, t, buf, (tmsize_t)bytecounts[t]) < 0) {
_TIFFfree(buf);
return (0);
}
}
_TIFFfree(buf);
return (1);
}
return (0);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 8
* fill-column: 78
* End:
*/