| Summary: | kfaxview lowres scaling issue/no LZW compression | ||
|---|---|---|---|
| Product: | [Unmaintained] kviewshell | Reporter: | Hans-Peter Jansen <hpj> |
| Component: | general | Assignee: | Matthias Hoelzer-Kluepfel <hoelzer> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | deller, hpj, kebekus |
| Priority: | NOR | ||
| Version First Reported In: | unspecified | ||
| Target Milestone: | --- | ||
| Platform: | Unlisted Binaries | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
|
Description
Hans-Peter Jansen
2006-07-23 23:36:29 UTC
SVN commit 578144 by whuss:
Support LZW compressed fax files.
This adds a dependency to libtiff.
BUG: 131263
M +5 -1 Makefile.am
A configure.in.bot
M +2 -2 fax/Makefile.am
A fax/configure.in.in
M +82 -37 fax/faxrenderer.cpp
M +6 -5 fax/faxrenderer.h
--- branches/work/kviewshell-0.7/kviewshell/plugins/Makefile.am #578143:578144
@@ -2,4 +2,8 @@
KVS_PDF_SUBDIR=pdf
endif
-SUBDIRS = djvu dvi fax $(KVS_PDF_SUBDIR) ps
+if include_TIFF
+KVS_FAX_SUBDIR=fax
+endif
+
+SUBDIRS = djvu dvi $(KVS_FAX_SUBDIR) $(KVS_PDF_SUBDIR) ps
--- branches/work/kviewshell-0.7/kviewshell/plugins/fax/Makefile.am #578143:578144
@@ -17,11 +17,11 @@
kde_module_LTLIBRARIES = kfaxviewpart.la
kfaxviewpart_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
kfaxviewpart_la_LIBADD = -lkdeprint -lkparts $(top_builddir)/kviewshell/shell/libkmultipage.la \
- libkfaximage/libkfaximage.la
+ libkfaximage/libkfaximage.la $(LIBTIFF)
kfaxviewpart_la_SOURCES = faxmultipage.cpp faxrenderer.cpp faxprintsettings.cpp
pluginsdir = $(kde_datadir)
-#plugins_DATA =
+#plugins_DATA =
partdesktopdir = $(kde_servicesdir)
partdesktop_DATA = kvs_fax_part.desktop
--- branches/work/kviewshell-0.7/kviewshell/plugins/fax/faxrenderer.cpp #578143:578144
@@ -33,7 +33,7 @@
//#define KF_DEBUG
FaxRenderer::FaxRenderer(KMultiPage* _multiPage)
- : DocumentRenderer(_multiPage)
+ : DocumentRenderer(_multiPage), fax(0)
{
#ifdef KF_DEBUG
kdError(kvs::fax) << "FaxRenderer( parent=" << par << " )" << endl;
@@ -79,7 +79,9 @@
double resolution = id.resolution;
- QImage img = fax.page(id.pageNumber - 1);
+ QImage img = getRawImage(id.pageNumber);
+ if (img.isNull())
+ return 0;
SimplePageSize psize = pageSizes[id.pageNumber - 1];
if (psize.isValid())
@@ -123,11 +125,17 @@
QMutexLocker locker(&mutex);
// If fname is the empty string, then this means: "close".
- if (fname.isEmpty()) {
+ if (fname.isEmpty())
+ {
+ if (fax)
+ {
+ TIFFClose(fax);
+ fax = 0;
+ }
kdDebug(kvs::fax) << "FaxRenderer::setFile( ... ) called with empty filename. Closing the file." << endl;
return true;
}
-
+
// Paranoid saftey checks: make sure the file actually exists, and
// that it is a file, not a directory. Otherwise, show an error
// message and exit..
@@ -143,51 +151,44 @@
// Now we assume that the file is fine and load the file into the
// fax member. We abort on error and give an error message.
- bool ok = fax.loadImage(filename);
+ fax = TIFFOpen(QFile::encodeName( filename ), "r");
+ if (!fax)
+ {
+ KMessageBox::error(parentWidget,
+ i18n("<qt><strong>File error.</strong> The specified file '%1' could not be loaded.</qt>").arg(filename),
+ i18n("File Error"));
- // It can happen that fax.loadImage() returns with 'ok == true', but
- // still the file could NOT be loaded. This happens, e.g. for TIFF
- // file that do NOT contain FAX, but other image formats. We handle
- // that case here also.
- if ( (!ok) || (fax.numPages() == 0)) {
- // Unfortunately, it can happen that fax.loadImage() fails WITHOUT
- // leaving an error message in fax.errorString(). We try to handle
- // this case gracefully.
- if (fax.errorString().isEmpty())
- KMessageBox::error( parentWidget,
- i18n("<qt><strong>File error.</strong> The specified file '%1' could not be loaded.</qt>").arg(filename),
- i18n("File Error"));
- else
- KMessageBox::detailedError( parentWidget,
- i18n("<qt><strong>File error.</strong> The specified file '%1' could not be loaded.</qt>").arg(filename),
- fax.errorString(),
- i18n("File Error"));
clear();
return false;
}
// Set the number of pages page sizes
- numPages = fax.numPages();
+ tdir_t dirs = TIFFNumberOfDirectories(fax);
+ numPages = dirs;
// Set the page size for the first page in the pageSizes array.
// The rest of the page sizes will be calculated on demand by the drawPage function.
pageSizes.resize(numPages);
Length w,h;
- if (numPages != 0) {
- for(Q_UINT16 pg=0; pg < numPages; pg++) {
- QSize pageSize = fax.page_size(pg);
- QPoint dpi = fax.page_dpi(pg);
- double dpix = dpi.x();
- double dpiy = dpi.y();
+ if (numPages != 0)
+ {
+ for(tdir_t pg = 0; pg < dirs; pg++)
+ {
+ if (!TIFFSetDirectory(fax, pg))
+ continue;
- if (dpix*dpiy < 1.0) {
- kdError(kvs::fax) << "File invalid resolutions, dpi x = " << dpix << ", dpi y = " << dpiy << ". This information will be ignored and 75 DPI assumed." << endl;
- dpix = dpiy = 75.0;
- }
+ QPoint dpi = getDPI(pg + 1);
- w.setLength_in_inch(pageSize.width() / dpix);
- h.setLength_in_inch(pageSize.height() / dpiy);
+ Q_UINT32 width = 0;
+ Q_UINT32 height = 0;
+
+ if (TIFFGetField(fax, TIFFTAG_IMAGEWIDTH, &width) != 1 ||
+ TIFFGetField(fax, TIFFTAG_IMAGELENGTH, &height) != 1 )
+ continue;
+
+ w.setLength_in_inch(width / (double)dpi.x());
+ h.setLength_in_inch(height / (double)dpi.y());
pageSizes[pg].setPageSize(w, h);
}
}
@@ -199,13 +200,57 @@
QImage FaxRenderer::getRawImage(PageNumber page)
{
- return fax.page(page - 1);
+ if (!TIFFSetDirectory(fax, page - 1))
+ return QImage();
+
+ Q_UINT32 width = 0;
+ Q_UINT32 height = 0;
+
+ if (TIFFGetField(fax, TIFFTAG_IMAGEWIDTH, &width) != 1 ||
+ TIFFGetField(fax, TIFFTAG_IMAGELENGTH, &height) != 1 )
+ return QImage();
+
+ QImage img(width, height, 32);
+ Q_UINT32* data = (Q_UINT32*)img.bits();
+
+ if (TIFFReadRGBAImageOriented(fax, width, height, data, ORIENTATION_TOPLEFT) != 0)
+ {
+ Q_UINT32 size = width * height;
+ for (Q_UINT32 i = 0; i < size; ++i)
+ {
+ Q_UINT32 red = (data[i] & 0x00FF0000) >> 16;
+ Q_UINT32 blue = (data[i] & 0x000000FF) << 16;
+ data[i] = (data[i] & 0xFF00FF00) + red + blue;
+ }
+ }
+ else
+ {
+ return QImage();
+ }
+
+ return img;
}
QPoint FaxRenderer::getDPI(PageNumber page)
{
- return fax.page_dpi(page - 1);
+ if (!TIFFSetDirectory(fax, page-1))
+ return QPoint(0, 0);
+
+ float dpix = 0.0;
+ float dpiy = 0.0;
+ if (TIFFGetField(fax, TIFFTAG_XRESOLUTION, &dpix) != 1 ||
+ TIFFGetField(fax, TIFFTAG_YRESOLUTION, &dpiy) != 1)
+ return QPoint(0, 0);
+
+ kdDebug(kvs::fax) << "resolutions, dpi x = " << dpix << ", dpi y = " << dpiy << "." << endl;
+
+ if (dpix <= 1 || dpiy <= 1) {
+ kdError(kvs::fax) << "File invalid resolutions, dpi x = " << dpix << ", dpi y = " << dpiy << ". This information will be ignored and 75 DPI assumed." << endl;
+ dpix = dpiy = 75;
+ }
+
+ return QPoint((int)dpix, (int)dpiy);
}
#include "faxrenderer.moc"
--- branches/work/kviewshell-0.7/kviewshell/plugins/fax/faxrenderer.h #578143:578144
@@ -23,12 +23,13 @@
#include "documentRenderer.h"
-#include "kfaximage.h"
+#include <tiffio.h>
+
class documentPage;
/*! \brief Well-documented minimal implementation of a documentRenderer for reading FAX files
-
+
This class provides a well-documented reference implementation of a
documentRenderer, suitable as a starting point for a real-world
implementation. This class is responsible for document loading and
@@ -65,7 +66,7 @@
is contained in the class "KFaxImage", to keep this reference
implementation short.
- @param fname the name of the file that should be opened.
+ @param fname the name of the file that should be opened.
*/
virtual bool setFile(const QString& fname, const KURL &);
@@ -84,8 +85,8 @@
QPoint getDPI(PageNumber page);
private:
- /** This class holds the fax file */
- KFaxImage fax;
+ /** This pointer holds the fax file */
+ TIFF* fax;
};
#endif
SVN commit 599807 by whuss:
port of commit 578144:
Support LZW compressed fax files.
This adds a dependency to libtiff.
CCBUG: 131263
M +7 -1 CMakeLists.txt
M +2 -4 fax/CMakeLists.txt
M +91 -46 fax/faxrenderer.cpp
M +6 -5 fax/faxrenderer.h
--- trunk/KDE/kdegraphics/kviewshell/plugins/CMakeLists.txt #599806:599807
@@ -9,8 +9,14 @@
if(FreeType2_FOUND)
add_subdirectory( dvi )
endif(FreeType2_FOUND)
-add_subdirectory( fax )
+macro_optional_find_package(TIFF)
+if(TIFF_FOUND)
+ add_subdirectory( fax )
+else(TIFF_FOUND)
+ message(STATUS "libtiff was not found. The KViewShell FAX-plugin will not be build.")
+endif(TIFF_FOUND)
+
macro_optional_find_package(PopplerQt4)
if (POPPLER_QT4_FOUND)
add_subdirectory( pdf )
--- trunk/KDE/kdegraphics/kviewshell/plugins/fax/CMakeLists.txt #599806:599807
@@ -1,9 +1,7 @@
-add_subdirectory( libkfaximage )
+include_directories( ${CMAKE_SOURCE_DIR}/kviewshell/shell )
-include_directories( ${CMAKE_SOURCE_DIR}/kviewshell/shell ${CMAKE_CURRENT_SOURCE_DIR}/libkfaximage )
-
########### next target ###############
set(kfaxviewpart_PART_SRCS faxmultipage.cpp faxrenderer.cpp faxprintsettings.cpp )
@@ -14,7 +12,7 @@
kde4_install_libtool_file( ${PLUGIN_INSTALL_DIR} kfaxviewpart )
-target_link_libraries(kfaxviewpart ${KDE4_KDEPRINT_LIBS} ${KDE4_KPARTS_LIBS} kmultipage kfaximage )
+target_link_libraries(kfaxviewpart ${KDE4_KDEPRINT_LIBS} ${KDE4_KPARTS_LIBS} ${TIFF_LIBRARIES} kmultipage )
install(TARGETS kfaxviewpart DESTINATION ${PLUGIN_INSTALL_DIR} )
--- trunk/KDE/kdegraphics/kviewshell/plugins/fax/faxrenderer.cpp #599806:599807
@@ -33,7 +33,7 @@
//#define KF_DEBUG
FaxRenderer::FaxRenderer(KMultiPage* _multiPage)
- : DocumentRenderer(_multiPage)
+ : DocumentRenderer(_multiPage), fax(0)
{
#ifdef KF_DEBUG
kError(kvs::fax) << "FaxRenderer( parent=" << par << " )" << endl;
@@ -79,7 +79,9 @@
double resolution = id.resolution;
- QImage img = fax.page(id.pageNumber - 1);
+ QImage img = getRawImage(id.pageNumber);
+ if (img.isNull())
+ return 0;
SimplePageSize psize = pageSizes[id.pageNumber - 1];
if (psize.isValid())
@@ -113,17 +115,6 @@
}
-QImage FaxRenderer::getRawImage(PageNumber page)
-{
- return fax.page(page - 1);
-}
-
-QPoint FaxRenderer::getDPI(PageNumber page)
-{
- return fax.page_dpi(page - 1);
-}
-
-
bool FaxRenderer::setFile(const QString &fname, const KUrl &)
{
#ifdef KF_DEBUG
@@ -134,11 +125,17 @@
QMutexLocker locker(&mutex);
// If fname is the empty string, then this means: "close".
- if (fname.isEmpty()) {
+ if (fname.isEmpty())
+ {
+ if (fax)
+ {
+ TIFFClose(fax);
+ fax = 0;
+ }
kDebug(kvs::fax) << "FaxRenderer::setFile( ... ) called with empty filename. Closing the file." << endl;
return true;
}
-
+
// Paranoid saftey checks: make sure the file actually exists, and
// that it is a file, not a directory. Otherwise, show an error
// message and exit..
@@ -154,51 +151,44 @@
// Now we assume that the file is fine and load the file into the
// fax member. We abort on error and give an error message.
- bool ok = fax.loadImage(filename);
+ fax = TIFFOpen(QFile::encodeName( filename ), "r");
+ if (!fax)
+ {
+ KMessageBox::error(parentWidget,
+ i18n("<qt><strong>File error.</strong> The specified file '%1' could not be loaded.</qt>").arg(filename),
+ i18n("File Error"));
- // It can happen that fax.loadImage() returns with 'ok == true', but
- // still the file could NOT be loaded. This happens, e.g. for TIFF
- // file that do NOT contain FAX, but other image formats. We handle
- // that case here also.
- if ( (!ok) || (fax.numPages() == 0)) {
- // Unfortunately, it can happen that fax.loadImage() fails WITHOUT
- // leaving an error message in fax.errorString(). We try to handle
- // this case gracefully.
- if (fax.errorString().isEmpty())
- KMessageBox::error( parentWidget,
- i18n("<qt><strong>File error.</strong> The specified file '%1' could not be loaded.</qt>", filename),
- i18n("File Error"));
- else
- KMessageBox::detailedError( parentWidget,
- i18n("<qt><strong>File error.</strong> The specified file '%1' could not be loaded.</qt>", filename),
- fax.errorString(),
- i18n("File Error"));
clear();
return false;
}
// Set the number of pages page sizes
- numPages = fax.numPages();
+ tdir_t dirs = TIFFNumberOfDirectories(fax);
+ numPages = dirs;
// Set the page size for the first page in the pageSizes array.
// The rest of the page sizes will be calculated on demand by the drawPage function.
pageSizes.resize(numPages);
Length w,h;
- if (numPages != 0) {
- for(quint16 pg=0; pg < numPages; pg++) {
- QSize pageSize = fax.page_size(pg);
- QPoint dpi = fax.page_dpi(pg);
- double dpix = dpi.x();
- double dpiy = dpi.y();
+ if (numPages != 0)
+ {
+ for(tdir_t pg = 0; pg < dirs; pg++)
+ {
+ if (!TIFFSetDirectory(fax, pg))
+ continue;
- if (dpix*dpiy < 1.0) {
- kError(kvs::fax) << "File invalid resolutions, dpi x = " << dpix << ", dpi y = " << dpiy << ". This information will be ignored and 75 DPI assumed." << endl;
- dpix = dpiy = 75.0;
- }
+ QPoint dpi = getDPI(pg + 1);
- w.setLength_in_inch(pageSize.width() / dpix);
- h.setLength_in_inch(pageSize.height() / dpiy);
+ quint32 width = 0;
+ quint32 height = 0;
+
+ if (TIFFGetField(fax, TIFFTAG_IMAGEWIDTH, &width) != 1 ||
+ TIFFGetField(fax, TIFFTAG_IMAGELENGTH, &height) != 1 )
+ continue;
+
+ w.setLength_in_inch(width / (double)dpi.x());
+ h.setLength_in_inch(height / (double)dpi.y());
pageSizes[pg].setPageSize(w, h);
}
}
@@ -208,4 +198,59 @@
}
+QImage FaxRenderer::getRawImage(PageNumber page)
+{
+ if (!TIFFSetDirectory(fax, page - 1))
+ return QImage();
+
+ quint32 width = 0;
+ quint32 height = 0;
+
+ if (TIFFGetField(fax, TIFFTAG_IMAGEWIDTH, &width) != 1 ||
+ TIFFGetField(fax, TIFFTAG_IMAGELENGTH, &height) != 1 )
+ return QImage();
+
+ QImage img(width, height, 32);
+ quint32* data = (quint32*)img.bits();
+
+ if (TIFFReadRGBAImageOriented(fax, width, height, data, ORIENTATION_TOPLEFT) != 0)
+ {
+ quint32 size = width * height;
+ for (quint32 i = 0; i < size; ++i)
+ {
+ Q_UINT32 red = (data[i] & 0x00FF0000) >> 16;
+ Q_UINT32 blue = (data[i] & 0x000000FF) << 16;
+ data[i] = (data[i] & 0xFF00FF00) + red + blue;
+ }
+ }
+ else
+ {
+ return QImage();
+ }
+
+ return img;
+}
+
+
+QPoint FaxRenderer::getDPI(PageNumber page)
+{
+ if (!TIFFSetDirectory(fax, page-1))
+ return QPoint(0, 0);
+
+ float dpix = 0.0;
+ float dpiy = 0.0;
+ if (TIFFGetField(fax, TIFFTAG_XRESOLUTION, &dpix) != 1 ||
+ TIFFGetField(fax, TIFFTAG_YRESOLUTION, &dpiy) != 1)
+ return QPoint(0, 0);
+
+ kDebug(kvs::fax) << "resolutions, dpi x = " << dpix << ", dpi y = " << dpiy << "." << endl;
+
+ if (dpix <= 1 || dpiy <= 1) {
+ kError(kvs::fax) << "File invalid resolutions, dpi x = " << dpix << ", dpi y = " << dpiy << ". This information will be ignored and 75 DPI assumed." << endl;
+ dpix = dpiy = 75;
+ }
+
+ return QPoint((int)dpix, (int)dpiy);
+}
+
#include "faxrenderer.moc"
--- trunk/KDE/kdegraphics/kviewshell/plugins/fax/faxrenderer.h #599806:599807
@@ -24,12 +24,13 @@
#include <qimage.h>
#include "documentRenderer.h"
-#include "kfaximage.h"
+#include <tiffio.h>
+
class documentPage;
/*! \brief Well-documented minimal implementation of a documentRenderer for reading FAX files
-
+
This class provides a well-documented reference implementation of a
documentRenderer, suitable as a starting point for a real-world
implementation. This class is responsible for document loading and
@@ -66,7 +67,7 @@
is contained in the class "KFaxImage", to keep this reference
implementation short.
- @param fname the name of the file that should be opened.
+ @param fname the name of the file that should be opened.
*/
virtual bool setFile(const QString& fname, const KUrl &);
@@ -85,8 +86,8 @@
QPoint getDPI(PageNumber page);
private:
- /** This class holds the fax file */
- KFaxImage fax;
+ /** This pointer holds the fax file */
+ TIFF* fax;
};
#endif
|