summaryrefslogtreecommitdiff
path: root/sdext/source/pdfimport/xpdfwrapper
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2009-06-15 08:47:44 +0000
committerIvo Hinkelmann <ihi@openoffice.org>2009-06-15 08:47:44 +0000
commit0ca8e0ea2db280fc7ce464611079b513a020199f (patch)
tree6542e82f1a655bf2419a256138dacbb7ecef3d83 /sdext/source/pdfimport/xpdfwrapper
parent19ed9c3a16889a49f6d6b222de40f7b377ff3e83 (diff)
CWS-TOOLING: integrate CWS pdfextfix02_DEV300
2009-05-10 11:23:59 +0200 pl r271736 : #i94755# adjust extension version, add extension icon 2009-05-08 17:06:50 +0200 pl r271726 : #i92909# handle some cases of mirroring 2009-05-08 14:51:37 +0200 pl r271720 : #i95270# cope with some rotated images 2009-05-08 11:37:46 +0200 pl r271709 : #i101327# recognize non breaking space also (thanks ayaniger) 2009-05-07 13:39:06 +0200 pl r271658 : #i92598# still more masked bitmap support 2009-05-07 10:44:41 +0200 pl r271638 : remove some compiler warnings 2009-05-07 09:59:56 +0200 pl r271633 : make test compile again 2009-05-06 21:12:55 +0200 pl r271612 : #i92903# handle two color images 2009-05-06 19:48:19 +0200 pl r271610 : soft masked images 2009-05-06 16:30:36 +0200 pl r271600 : #i92598# use masked PNG images for drawMask 2009-05-05 18:40:06 +0200 pl r271550 : #i90617# #i92598# some workarounds for mask bitmaps 2009-05-04 18:53:09 +0200 pl r271479 : #i94755# add supported for encrypted PDF files
Diffstat (limited to 'sdext/source/pdfimport/xpdfwrapper')
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/makefile.mk3
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx244
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx6
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx411
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx92
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx50
6 files changed, 721 insertions, 85 deletions
diff --git a/sdext/source/pdfimport/xpdfwrapper/makefile.mk b/sdext/source/pdfimport/xpdfwrapper/makefile.mk
index 8ce3fb718228..796bef066cde 100644
--- a/sdext/source/pdfimport/xpdfwrapper/makefile.mk
+++ b/sdext/source/pdfimport/xpdfwrapper/makefile.mk
@@ -57,8 +57,9 @@ UWINAPILIB:=
APP1TARGET=$(TARGET)
APP1LIBSALCPPRT=
APP1OBJS= \
- $(OBJ)$/wrapper_gpl.obj $(OBJ)/pdfioutdev_gpl.obj
+ $(OBJ)$/wrapper_gpl.obj $(OBJ)/pdfioutdev_gpl.obj $(OBJ)/pnghelper.obj
+APP1STDLIBS+=$(ZLIB3RDLIB)
.IF "$(SYSTEM_POPPLER)" == "YES"
APP1STDLIBS+=$(POPPLER_LIBS)
diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
index 63c62ce786de..3c72a27e6d35 100644
--- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
@@ -35,6 +35,7 @@
************************************************************************/
#include "pdfioutdev_gpl.hxx"
+#include "pnghelper.hxx"
#include <stdlib.h>
#include <stdio.h>
@@ -95,8 +96,6 @@ const char* escapeLineFeed( const char* pStr )
/// for the initial std::vector capacity when copying stream from xpdf
#define WRITE_BUFFER_INITIAL_CAPACITY (1024*100)
-typedef std::vector<char> OutputBuffer;
-
void initBuf(OutputBuffer& io_rBuffer)
{
io_rBuffer.reserve(WRITE_BUFFER_INITIAL_CAPACITY);
@@ -135,7 +134,7 @@ void writeJpeg_( OutputBuffer& o_rOutputBuf, Stream* str, bool bWithLinefeed )
str->close();
}
-void writePbm_(OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed)
+void writePbm_(OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed, bool bInvert )
{
// write as PBM (char by char, to avoid stdlib lineend messing)
o_rOutputBuf.clear();
@@ -163,19 +162,142 @@ void writePbm_(OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, b
str->reset();
// copy the raw stream
- for( int i=0; i<size; ++i)
- o_rOutputBuf.push_back(static_cast<char>(str->getChar()));
+ if( bInvert )
+ {
+ for( int i=0; i<size; ++i)
+ o_rOutputBuf.push_back(static_cast<char>(str->getChar() ^ 0xff));
+ }
+ else
+ {
+ for( int i=0; i<size; ++i)
+ o_rOutputBuf.push_back(static_cast<char>(str->getChar()));
+ }
str->close();
}
+void writePpm_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxImageColorMap* colorMap,
+ bool bWithLinefeed )
+{
+ // write as PPM (char by char, to avoid stdlib lineend messing)
+ o_rOutputBuf.clear();
+ o_rOutputBuf.resize(WRITE_BUFFER_SIZE);
+ o_rOutputBuf[0] = 'P';
+ o_rOutputBuf[1] = '6';
+ o_rOutputBuf[2] = '\n';
+ int nOutLen = snprintf(&o_rOutputBuf[3], WRITE_BUFFER_SIZE-10, "%d %d", width, height);
+ if( nOutLen < 0 )
+ nOutLen = WRITE_BUFFER_SIZE-10;
+ o_rOutputBuf[3+nOutLen] ='\n';
+ o_rOutputBuf[3+nOutLen+1]='2';
+ o_rOutputBuf[3+nOutLen+2]='5';
+ o_rOutputBuf[3+nOutLen+3]='5';
+ o_rOutputBuf[3+nOutLen+4]='\n';
+ o_rOutputBuf[3+nOutLen+5]=0;
+
+ const int header_size = 3+nOutLen+5;
+ const int size = width*height*3 + header_size;
+
+ printf( " PPM %d", size );
+ if( bWithLinefeed )
+ printf("\n");
+
+ // trim buffer to exact header size
+ o_rOutputBuf.resize(header_size);
+
+ // initialize stream
+ Guchar *p;
+ GfxRGB rgb;
+ ImageStream* imgStr =
+ new ImageStream(str,
+ width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ for( int y=0; y<height; ++y)
+ {
+ p = imgStr->getLine();
+ for( int x=0; x<width; ++x)
+ {
+ colorMap->getRGB(p, &rgb);
+ o_rOutputBuf.push_back(colToByte(rgb.r));
+ o_rOutputBuf.push_back(colToByte(rgb.g));
+ o_rOutputBuf.push_back(colToByte(rgb.b));
+
+ p +=colorMap->getNumPixelComps();
+ }
+ }
+
+ delete imgStr;
+
+}
+
+// call this only for 1 bit image streams !
+void writePng_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxRGB& zeroColor,
+ GfxRGB& oneColor,
+ bool bIsMask,
+ bool bWithLinefeed )
+{
+ o_rOutputBuf.clear();
+
+ // get png image
+ PngHelper::createPng( o_rOutputBuf, str, width, height, zeroColor, oneColor, bIsMask );
+
+ printf( " PNG %d", (int)o_rOutputBuf.size() );
+ if( bWithLinefeed )
+ printf("\n");
+}
+
+void writePng_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap,
+ bool bWithLinefeed )
+{
+ o_rOutputBuf.clear();
+
+ // get png image
+ PngHelper::createPng( o_rOutputBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap );
+
+ printf( " PNG %d", (int)o_rOutputBuf.size() );
+ if( bWithLinefeed )
+ printf("\n");
+}
+
+void writePng_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, bool maskInvert,
+ bool bWithLinefeed )
+{
+ o_rOutputBuf.clear();
+
+ // get png image
+ PngHelper::createPng( o_rOutputBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert );
+
+ printf( " PNG %d", (int)o_rOutputBuf.size() );
+ if( bWithLinefeed )
+ printf("\n");
+}
+
// stolen from ImageOutputDev.cc
-void writeMask_( OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed )
+void writeMask_( OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed, bool bInvert )
{
if( str->getKind() == strDCT )
writeJpeg_(o_rOutputBuf, str, bWithLinefeed);
else
- writePbm_(o_rOutputBuf, str, width, height, bWithLinefeed);
+ writePbm_(o_rOutputBuf, str, width, height, bWithLinefeed, bInvert );
}
void writeImage_( OutputBuffer& o_rOutputBuf,
@@ -195,62 +317,21 @@ void writeImage_( OutputBuffer& o_rOutputBuf,
else if (colorMap->getNumPixelComps() == 1 &&
colorMap->getBits() == 1)
{
- writePbm_(o_rOutputBuf, str, width, height, bWithLinefeed);
- }
- else
- {
- // write as PPM (char by char, to avoid stdlib lineend messing)
- o_rOutputBuf.clear();
- o_rOutputBuf.resize(WRITE_BUFFER_SIZE);
- o_rOutputBuf[0] = 'P';
- o_rOutputBuf[1] = '6';
- o_rOutputBuf[2] = '\n';
- int nOutLen = snprintf(&o_rOutputBuf[3], WRITE_BUFFER_SIZE-10, "%d %d", width, height);
- if( nOutLen < 0 )
- nOutLen = WRITE_BUFFER_SIZE-10;
- o_rOutputBuf[3+nOutLen] ='\n';
- o_rOutputBuf[3+nOutLen+1]='2';
- o_rOutputBuf[3+nOutLen+2]='5';
- o_rOutputBuf[3+nOutLen+3]='5';
- o_rOutputBuf[3+nOutLen+4]='\n';
- o_rOutputBuf[3+nOutLen+5]=0;
-
- const int header_size = 3+nOutLen+5;
- const int size = width*height*3 + header_size;
-
- printf( " PPM %d", size );
- if( bWithLinefeed )
- printf("\n");
-
- // trim buffer to exact header size
- o_rOutputBuf.resize(header_size);
-
- // initialize stream
- Guchar *p;
- GfxRGB rgb;
- ImageStream* imgStr =
- new ImageStream(str,
- width,
- colorMap->getNumPixelComps(),
- colorMap->getBits());
- imgStr->reset();
-
- for( int y=0; y<height; ++y)
+ // this is a two color bitmap, write a png
+ // provide default colors
+ GfxRGB zeroColor = { 0, 0, 0 },
+ oneColor = { byteToCol( 0xff ), byteToCol( 0xff ), byteToCol( 0xff ) };
+ if( colorMap->getColorSpace()->getMode() == csIndexed || colorMap->getColorSpace()->getMode() == csDeviceGray )
{
- p = imgStr->getLine();
- for( int x=0; x<width; ++x)
- {
- colorMap->getRGB(p, &rgb);
- o_rOutputBuf.push_back(colToByte(rgb.r));
- o_rOutputBuf.push_back(colToByte(rgb.g));
- o_rOutputBuf.push_back(colToByte(rgb.b));
-
- p +=colorMap->getNumPixelComps();
- }
+ Guchar nIndex = 0;
+ colorMap->getRGB( &nIndex, &zeroColor );
+ nIndex = 1;
+ colorMap->getRGB( &nIndex, &oneColor );
}
-
- delete imgStr;
+ writePng_( o_rOutputBuf, str, width, height, zeroColor, oneColor, false, bWithLinefeed );
}
+ else
+ writePpm_( o_rOutputBuf, str, width, height, colorMap, bWithLinefeed );
}
// forwarders
@@ -269,11 +350,13 @@ inline void writeImageLF( OutputBuffer& o_rOutputBuf,
inline void writeMask( OutputBuffer& o_rOutputBuf,
Stream* str,
int width,
- int height ) { writeMask_(o_rOutputBuf,str,width,height,false); }
+ int height,
+ bool bInvert ) { writeMask_(o_rOutputBuf,str,width,height,false,bInvert); }
inline void writeMaskLF( OutputBuffer& o_rOutputBuf,
Stream* str,
int width,
- int height ) { writeMask_(o_rOutputBuf,str,width,height,true); }
+ int height,
+ bool bInvert ) { writeMask_(o_rOutputBuf,str,width,height,true,bInvert); }
// ------------------------------------------------------------------
@@ -358,7 +441,7 @@ void PDFOutDev::printPath( GfxPath* pPath ) const
PDFOutDev::PDFOutDev( PDFDoc* pDoc ) :
m_pDoc( pDoc ),
m_aFontMap(),
- m_pUtf8Map( new UnicodeMap("UTF-8", gTrue, &mapUTF8) )
+ m_pUtf8Map( new UnicodeMap((char*)"UTF-8", gTrue, &mapUTF8) )
{
}
@@ -704,14 +787,29 @@ void PDFOutDev::endTextObject(GfxState*)
printf( "endTextObject\n" );
}
-void PDFOutDev::drawImageMask(GfxState*, Object*, Stream* str,
+void PDFOutDev::drawImageMask(GfxState* pState, Object*, Stream* str,
int width, int height, GBool invert,
GBool /*inlineImg*/ )
{
OutputBuffer aBuf; initBuf(aBuf);
printf( "drawMask %d %d %d", width, height, invert );
- writeMaskLF(aBuf, str, width, height);
+
+ int bitsPerComponent = 1;
+ StreamColorSpaceMode csMode = streamCSNone;
+ str->getImageParams( &bitsPerComponent, &csMode );
+ if( bitsPerComponent == 1 && (csMode == streamCSNone || csMode == streamCSDeviceGray) )
+ {
+ GfxRGB oneColor = { dblToCol( 1.0 ), dblToCol( 1.0 ), dblToCol( 1.0 ) };
+ GfxRGB zeroColor = { dblToCol( 0.0 ), dblToCol( 0.0 ), dblToCol( 0.0 ) };
+ pState->getFillColorSpace()->getRGB( pState->getFillColor(), &zeroColor );
+ if( invert )
+ writePng_( aBuf, str, width, height, oneColor, zeroColor, true, true );
+ else
+ writePng_( aBuf, str, width, height, zeroColor, oneColor, true, true );
+ }
+ else
+ writeMaskLF(aBuf, str, width, height, invert != 0);
writeBinaryBuffer(aBuf);
}
@@ -768,13 +866,19 @@ void PDFOutDev::drawMaskedImage(GfxState*, Object*, Stream* str,
GBool maskInvert)
{
OutputBuffer aBuf; initBuf(aBuf);
+ printf( "drawImage %d %d 0", width, height );
+ writePng_( aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert, true );
+ writeBinaryBuffer( aBuf );
+ #if 0
+ OutputBuffer aBuf; initBuf(aBuf);
OutputBuffer aMaskBuf; initBuf(aMaskBuf);
- printf( "drawMaskedImage %d %d %d %d %d", width, height, maskWidth, maskHeight, maskInvert );
+ printf( "drawMaskedImage %d %d %d %d %d", width, height, maskWidth, maskHeight, 0 /*maskInvert note: currently we do inversion here*/ );
writeImage( aBuf, str, width, height, colorMap );
- writeMaskLF( aMaskBuf, maskStr, width, height );
+ writeMaskLF( aMaskBuf, maskStr, width, height, maskInvert );
writeBinaryBuffer(aBuf);
writeBinaryBuffer(aMaskBuf);
+ #endif
}
void PDFOutDev::drawSoftMaskedImage(GfxState*, Object*, Stream* str,
@@ -785,6 +889,11 @@ void PDFOutDev::drawSoftMaskedImage(GfxState*, Object*, Stream* str,
GfxImageColorMap* maskColorMap )
{
OutputBuffer aBuf; initBuf(aBuf);
+ printf( "drawImage %d %d 0", width, height );
+ writePng_( aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap, true );
+ writeBinaryBuffer( aBuf );
+ #if 0
+ OutputBuffer aBuf; initBuf(aBuf);
OutputBuffer aMaskBuf; initBuf(aMaskBuf);
printf( "drawSoftMaskedImage %d %d %d %d", width, height, maskWidth, maskHeight );
@@ -792,6 +901,7 @@ void PDFOutDev::drawSoftMaskedImage(GfxState*, Object*, Stream* str,
writeImageLF( aMaskBuf, maskStr, maskWidth, maskHeight, maskColorMap );
writeBinaryBuffer(aBuf);
writeBinaryBuffer(aMaskBuf);
+ #endif
}
void PDFOutDev::setPageNum( int nNumPages )
diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx
index eb4d130f6a79..43a1038f02d6 100644
--- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx
+++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx
@@ -64,6 +64,7 @@
#endif
#include <hash_map>
+#include <vector>
class GfxPath;
class GfxFont;
@@ -286,5 +287,10 @@ namespace pdfi
extern FILE* g_binary_out;
+// note: if you ever hcange Output_t, please keep in mind that the current code
+// relies on it being of 8 bit size
+typedef char Output_t;
+typedef std::vector< Output_t > OutputBuffer;
+
#endif /* INCLUDED_PDFI_OUTDEV_HXX */
diff --git a/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx b/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx
new file mode 100644
index 000000000000..91b886de1689
--- /dev/null
+++ b/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx
@@ -0,0 +1,411 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU General Public License Version 2.
+ *
+ *
+ * GNU General Public License, version 2
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ ************************************************************************/
+
+#include "pnghelper.hxx"
+
+#include "zlib/zlib.h"
+
+using namespace pdfi;
+
+// checksum helpers, courtesy of libpng.org
+
+/* Table of CRCs of all 8-bit messages. */
+sal_uInt32 PngHelper::crc_table[256];
+
+/* Flag: has the table been computed? Initially false. */
+bool PngHelper::bCRCTableInit = true;
+
+/* Make the table for a fast CRC. */
+void PngHelper::initCRCTable()
+{
+ for (sal_uInt32 n = 0; n < 256; n++)
+ {
+ sal_uInt32 c = n;
+ for (int k = 0; k < 8; k++)
+ {
+ if (c & 1)
+ c = 0xedb88320L ^ (c >> 1);
+ else
+ c = c >> 1;
+ }
+ crc_table[n] = c;
+ }
+ bCRCTableInit = false;
+}
+
+/* Update a running CRC with the bytes buf[0..len-1]--the CRC
+ should be initialized to all 1's, and the transmitted value
+ is the 1's complement of the final running CRC (see the
+ crc() routine below)). */
+
+void PngHelper::updateCRC( sal_uInt32& io_rCRC, const sal_uInt8* i_pBuf, size_t i_nLen )
+{
+ if( bCRCTableInit )
+ initCRCTable();
+
+ sal_uInt32 nCRC = io_rCRC;
+ for( size_t n = 0; n < i_nLen; n++ )
+ nCRC = crc_table[(nCRC ^ i_pBuf[n]) & 0xff] ^ (nCRC >> 8);
+ io_rCRC = nCRC;
+}
+
+sal_uInt32 PngHelper::getCRC( const sal_uInt8* i_pBuf, size_t i_nLen )
+{
+ sal_uInt32 nCRC = 0xffffffff;
+ updateCRC( nCRC, i_pBuf, i_nLen );
+ return nCRC ^ 0xffffffff;
+}
+
+sal_uInt32 PngHelper::deflateBuffer( const Output_t* i_pBuf, size_t i_nLen, OutputBuffer& o_rOut )
+{
+ size_t nOrigSize = o_rOut.size();
+
+ // prepare z stream
+ z_stream aStream;
+ aStream.zalloc = Z_NULL;
+ aStream.zfree = Z_NULL;
+ aStream.opaque = Z_NULL;
+ deflateInit( &aStream, Z_BEST_COMPRESSION );
+ aStream.avail_in = uInt(i_nLen);
+ aStream.next_in = (Bytef*)i_pBuf;
+
+ sal_uInt8 aOutBuf[ 32768 ];
+ do
+ {
+ aStream.avail_out = sizeof( aOutBuf );
+ aStream.next_out = aOutBuf;
+
+ if( deflate( &aStream, Z_FINISH ) == Z_STREAM_ERROR )
+ {
+ deflateEnd( &aStream );
+ // scrao the data of this broken stream
+ o_rOut.resize( nOrigSize );
+ return 0;
+ }
+
+ // append compressed bytes
+ sal_uInt32 nCompressedBytes = sizeof( aOutBuf ) - aStream.avail_out;
+ if( nCompressedBytes )
+ o_rOut.insert( o_rOut.end(), aOutBuf, aOutBuf+nCompressedBytes );
+
+ } while( aStream.avail_out == 0 );
+
+ // cleanup
+ deflateEnd( &aStream );
+
+ return sal_uInt32( o_rOut.size() - nOrigSize );
+}
+
+void PngHelper::appendFileHeader( OutputBuffer& o_rOutputBuf )
+{
+ static const Output_t aHeader[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
+
+ o_rOutputBuf.insert( o_rOutputBuf.end(), aHeader, aHeader + sizeof(aHeader)/sizeof(aHeader[0]) );
+}
+
+size_t PngHelper::startChunk( const char* pChunkName, OutputBuffer& o_rOutputBuf )
+{
+ size_t nIndex = sal_uInt32( o_rOutputBuf.size() );
+ o_rOutputBuf.insert( o_rOutputBuf.end(), 4, 0 );
+ o_rOutputBuf.push_back( pChunkName[0] );
+ o_rOutputBuf.push_back( pChunkName[1] );
+ o_rOutputBuf.push_back( pChunkName[2] );
+ o_rOutputBuf.push_back( pChunkName[3] );
+ return nIndex;
+}
+
+void PngHelper::set( sal_uInt32 i_nValue, OutputBuffer& o_rOutputBuf, size_t i_nIndex )
+{
+ o_rOutputBuf[ i_nIndex ] = (i_nValue & 0xff000000) >> 24;
+ o_rOutputBuf[ i_nIndex+1 ] = (i_nValue & 0x00ff0000) >> 16;
+ o_rOutputBuf[ i_nIndex+2 ] = (i_nValue & 0x0000ff00) >> 8;
+ o_rOutputBuf[ i_nIndex+3 ] = (i_nValue & 0x000000ff);
+}
+
+void PngHelper::endChunk( size_t nStart, OutputBuffer& o_rOutputBuf )
+{
+ if( nStart+8 > o_rOutputBuf.size() )
+ return; // something broken is going on
+
+ // update chunk length
+ size_t nLen = o_rOutputBuf.size() - nStart;
+ sal_uInt32 nDataLen = sal_uInt32(nLen)-8;
+ set( nDataLen, o_rOutputBuf, nStart );
+
+ // append chunk crc
+ sal_uInt32 nChunkCRC = getCRC( (sal_uInt8*)&o_rOutputBuf[nStart+4], nLen-4 );
+ append( nChunkCRC, o_rOutputBuf );
+}
+
+void PngHelper::appendIHDR( OutputBuffer& o_rOutputBuf, int width, int height, int depth, int colortype )
+{
+ size_t nStart = startChunk( "IHDR", o_rOutputBuf );
+ append( width, o_rOutputBuf );
+ append( height, o_rOutputBuf );
+ o_rOutputBuf.push_back( Output_t(depth) );
+ o_rOutputBuf.push_back( Output_t(colortype) );
+ o_rOutputBuf.push_back( 0 ); // compression method deflate
+ o_rOutputBuf.push_back( 0 ); // filtering method 0 (default)
+ o_rOutputBuf.push_back( 0 ); // no interlacing
+ endChunk( nStart, o_rOutputBuf );
+}
+
+void PngHelper::appendIEND( OutputBuffer& o_rOutputBuf )
+{
+ size_t nStart = startChunk( "IEND", o_rOutputBuf );
+ endChunk( nStart, o_rOutputBuf );
+}
+
+void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxRGB& zeroColor,
+ GfxRGB& oneColor,
+ bool bIsMask
+ )
+{
+ appendFileHeader( o_rOutputBuf );
+ appendIHDR( o_rOutputBuf, width, height, 1, 3 );
+
+ // write palette
+ size_t nIdx = startChunk( "PLTE", o_rOutputBuf );
+ // write colors 0 and 1
+ o_rOutputBuf.push_back(colToByte(zeroColor.r));
+ o_rOutputBuf.push_back(colToByte(zeroColor.g));
+ o_rOutputBuf.push_back(colToByte(zeroColor.b));
+ o_rOutputBuf.push_back(colToByte(oneColor.r));
+ o_rOutputBuf.push_back(colToByte(oneColor.g));
+ o_rOutputBuf.push_back(colToByte(oneColor.b));
+ // end PLTE chunk
+ endChunk( nIdx, o_rOutputBuf );
+
+ if( bIsMask )
+ {
+ // write tRNS chunk
+ nIdx = startChunk( "tRNS", o_rOutputBuf );
+ o_rOutputBuf.push_back( 0xff );
+ o_rOutputBuf.push_back( 0 );
+ // end tRNS chunk
+ endChunk( nIdx, o_rOutputBuf );
+ }
+
+ // create scan line data buffer
+ OutputBuffer aScanlines;
+ int nLineSize = (width + 7)/8;
+ aScanlines.reserve( nLineSize * height + height );
+
+ str->reset();
+ for( int y = 0; y < height; y++ )
+ {
+ // determine filter type (none) for this scanline
+ aScanlines.push_back( 0 );
+ for( int x = 0; x < nLineSize; x++ )
+ aScanlines.push_back( str->getChar() );
+ }
+
+ // begin IDAT chunk for scanline data
+ nIdx = startChunk( "IDAT", o_rOutputBuf );
+ // compress scanlines
+ deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
+ // end IDAT chunk
+ endChunk( nIdx, o_rOutputBuf );
+
+ // output IEND
+ appendIEND( o_rOutputBuf );
+}
+
+void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap )
+{
+ appendFileHeader( o_rOutputBuf );
+ appendIHDR( o_rOutputBuf, width, height, 8, 6 ); // RGBA image
+
+ // initialize stream
+ Guchar *p, *pm;
+ GfxRGB rgb;
+ GfxGray alpha;
+ ImageStream* imgStr =
+ new ImageStream(str,
+ width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ // create scan line data buffer
+ OutputBuffer aScanlines;
+ aScanlines.reserve( width*height*4 + height );
+
+ for( int y=0; y<height; ++y)
+ {
+ aScanlines.push_back( 0 );
+ p = imgStr->getLine();
+ for( int x=0; x<width; ++x)
+ {
+ colorMap->getRGB(p, &rgb);
+ aScanlines.push_back(colToByte(rgb.r));
+ aScanlines.push_back(colToByte(rgb.g));
+ aScanlines.push_back(colToByte(rgb.b));
+ aScanlines.push_back( 0xff );
+
+ p +=colorMap->getNumPixelComps();
+ }
+ }
+
+
+ // now fill in the mask data
+
+ // CAUTION: originally this was done in one single loop
+ // it caused merry chaos; the reason is that maskStr and str are
+ // not independent streams, it happens that reading one advances
+ // the other, too. Hence the two passes are imperative !
+
+ // initialize mask stream
+ ImageStream* imgStrMask =
+ new ImageStream(maskStr,
+ maskWidth,
+ maskColorMap->getNumPixelComps(),
+ maskColorMap->getBits());
+
+ imgStrMask->reset();
+ for( int y = 0; y < maskHeight; ++y )
+ {
+ pm = imgStrMask->getLine();
+ for( int x = 0; x < maskWidth; ++x )
+ {
+ maskColorMap->getGray(pm,&alpha);
+ pm += maskColorMap->getNumPixelComps();
+ int nIndex = (y*height/maskHeight) * (width*4+1) + // mapped line
+ (x*width/maskWidth)*4 + 1 + 3 // mapped column
+ ;
+ aScanlines[ nIndex ] = colToByte(alpha);
+ }
+ }
+
+ delete imgStr;
+ delete imgStrMask;
+
+ // begind IDAT chunk for scanline data
+ size_t nIdx = startChunk( "IDAT", o_rOutputBuf );
+ // compress scanlines
+ deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
+ // end IDAT chunk
+ endChunk( nIdx, o_rOutputBuf );
+ // output IEND
+ appendIEND( o_rOutputBuf );
+}
+
+// one bit mask; 0 bits opaque
+void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight,
+ bool maskInvert
+ )
+{
+ appendFileHeader( o_rOutputBuf );
+ appendIHDR( o_rOutputBuf, width, height, 8, 6 ); // RGBA image
+
+ // initialize stream
+ Guchar *p;
+ GfxRGB rgb;
+ ImageStream* imgStr =
+ new ImageStream(str,
+ width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ // create scan line data buffer
+ OutputBuffer aScanlines;
+ aScanlines.reserve( width*height*4 + height );
+
+ for( int y=0; y<height; ++y)
+ {
+ aScanlines.push_back( 0 );
+ p = imgStr->getLine();
+ for( int x=0; x<width; ++x)
+ {
+ colorMap->getRGB(p, &rgb);
+ aScanlines.push_back(colToByte(rgb.r));
+ aScanlines.push_back(colToByte(rgb.g));
+ aScanlines.push_back(colToByte(rgb.b));
+ aScanlines.push_back( 0xff );
+
+ p +=colorMap->getNumPixelComps();
+ }
+ }
+
+
+ // now fill in the mask data
+
+ // CAUTION: originally this was done in one single loop
+ // it caused merry chaos; the reason is that maskStr and str are
+ // not independent streams, it happens that reading one advances
+ // the other, too. Hence the two passes are imperative !
+
+ // initialize mask stream
+ ImageStream* imgStrMask =
+ new ImageStream(maskStr, maskWidth, 1, 1);
+
+ imgStrMask->reset();
+ for( int y = 0; y < maskHeight; ++y )
+ {
+ for( int x = 0; x < maskWidth; ++x )
+ {
+ Guchar aPixel = 0;
+ imgStrMask->getPixel( &aPixel );
+ int nIndex = (y*height/maskHeight) * (width*4+1) + // mapped line
+ (x*width/maskWidth)*4 + 1 + 3 // mapped column
+ ;
+ if( maskInvert )
+ aScanlines[ nIndex ] = aPixel ? 0xff : 0x00;
+ else
+ aScanlines[ nIndex ] = aPixel ? 0x00 : 0xff;
+ }
+ }
+
+ delete imgStr;
+ delete imgStrMask;
+
+ // begind IDAT chunk for scanline data
+ size_t nIdx = startChunk( "IDAT", o_rOutputBuf );
+ // compress scanlines
+ deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
+ // end IDAT chunk
+ endChunk( nIdx, o_rOutputBuf );
+ // output IEND
+ appendIEND( o_rOutputBuf );
+}
+
diff --git a/sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx b/sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx
new file mode 100644
index 000000000000..34fe4757f382
--- /dev/null
+++ b/sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU General Public License Version 2.
+ *
+ *
+ * GNU General Public License, version 2
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ ************************************************************************/
+#ifndef _IPDF_PNGHELPER_HXX
+#define _IPDF_PNGHELPER_HXX
+
+#include "sal/types.h"
+#include "pdfioutdev_gpl.hxx"
+
+
+namespace pdfi
+{
+ class PngHelper
+ {
+ static sal_uInt32 crc_table[ 256 ];
+ static bool bCRCTableInit;
+
+ static void initCRCTable();
+ static void appendFileHeader( OutputBuffer& o_rOutputBuf );
+ static size_t startChunk( const char* pChunkName, OutputBuffer& o_rOut );
+ static void endChunk( size_t nStart, OutputBuffer& o_rOut );
+
+ static void set( sal_uInt32 i_nValue, OutputBuffer& o_rOutputBuf, size_t i_nIndex );
+ static void append( sal_uInt32 i_nValue, OutputBuffer& o_rOutputBuf )
+ {
+ size_t nCur = o_rOutputBuf.size();
+ o_rOutputBuf.insert( o_rOutputBuf.end(), 4, 0 );
+ set( i_nValue, o_rOutputBuf, nCur );
+ }
+
+ static void appendIHDR( OutputBuffer& o_rOutputBuf, int width, int height, int depth, int colortype );
+ static void appendIEND( OutputBuffer& o_rOutputBuf );
+
+ public:
+ static void updateCRC( sal_uInt32& io_rCRC, const sal_uInt8* i_pBuf, size_t i_nLen );
+ static sal_uInt32 getCRC( const sal_uInt8* i_pBuf, size_t i_nLen );
+
+ // deflates the passed buff i_pBuf and appends it to the output vector
+ // returns the number of bytes added to the output
+ static sal_uInt32 deflateBuffer( const Output_t* i_pBuf, size_t i_nLen, OutputBuffer& o_rOut );
+
+ static void createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxRGB& zeroColor,
+ GfxRGB& oneColor,
+ bool bIsMask
+ );
+ static void createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap );
+
+ // for one bit masks
+ static void createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, bool maskInvert );
+
+ };
+}
+
+#endif
diff --git a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
index 687f905e8355..fadf71e2c20e 100644
--- a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
@@ -49,12 +49,12 @@ static char userPassword[33] = "\001";
static char outputFile[256] = "\001";
static ArgDesc argDesc[] = {
- {"-f", argString, outputFile, sizeof(outputFile),
- "output file for binary streams"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
+ {(char*)"-f", argString, outputFile, sizeof(outputFile),
+ (char*)"output file for binary streams"},
+ {(char*)"-opw", argString, ownerPassword, sizeof(ownerPassword),
+ (char*)"owner password (for encrypted files)"},
+ {(char*)"-upw", argString, userPassword, sizeof(userPassword),
+ (char*)"user password (for encrypted files)"},
{NULL, argString, NULL, 0, NULL }
};
#else
@@ -104,7 +104,7 @@ int main(int argc, char **argv)
// read config file
globalParams = new GlobalParams(
#ifndef SYSTEM_POPPLER
- ""
+ (char*)""
#endif
);
globalParams->setErrQuiet(gTrue);
@@ -112,6 +112,23 @@ int main(int argc, char **argv)
globalParams->setupBaseFonts(NULL);
#endif
+ // try to read a possible open password form stdin
+ char aPwBuf[34];
+ aPwBuf[33] = 0;
+ if( ! fgets( aPwBuf, sizeof(aPwBuf)-1, stdin ) )
+ aPwBuf[0] = 0; // mark as empty
+ else
+ {
+ for( unsigned int i = 0; i < sizeof(aPwBuf); i++ )
+ {
+ if( aPwBuf[i] == '\n' )
+ {
+ aPwBuf[i] = 0;
+ break;
+ }
+ }
+ }
+
// PDFDoc takes over ownership for all strings below
GooString* pFileName = new GooString(argv[1]);
GooString* pTempErrFileName = new GooString("_err.pdf");
@@ -121,12 +138,14 @@ int main(int argc, char **argv)
// check for password string(s)
- GooString* pOwnerPasswordStr(
- ownerPassword[0] != '\001' ? new GooString(ownerPassword)
- : (GooString *)NULL );
- GooString* pUserPasswordStr(
- userPassword[0] != '\001' ? new GooString(userPassword)
- : (GooString *)NULL );
+ GooString* pOwnerPasswordStr( ownerPassword[0] != '\001'
+ ? new GooString(ownerPassword)
+ : (GooString *)NULL );
+ GooString* pUserPasswordStr( aPwBuf[0] != 0
+ ? new GooString( aPwBuf )
+ : ( userPassword[0] != '\001'
+ ? new GooString(userPassword)
+ : (GooString *)NULL ) );
if( outputFile[0] != '\001' )
g_binary_out = fopen(outputFile,"wb");
@@ -150,10 +169,7 @@ int main(int argc, char **argv)
!aDoc.okToPrint() ||
!aDoc.okToChange()||
!aDoc.okToCopy()||
- !aDoc.okToAddNotes()||
- (userPassword[0] != '\001')||
- (ownerPassword[0] != '\001')
- )
+ !aDoc.okToAddNotes() )
{
pdfi::PDFOutDev* pOutDev( new pdfi::PDFOutDev(&aErrDoc) );