30sal_uInt32 PngHelper::crc_table[256];
33bool PngHelper::bCRCTableInit =
true;
36void PngHelper::initCRCTable()
38 for (sal_uInt32
n = 0;
n < 256;
n++)
41 for (
int k = 0; k < 8; k++)
44 c = 0xedb88320L ^ (c >> 1);
63 sal_uInt32 nCRC = io_rCRC;
64 for(
size_t n = 0;
n < i_nLen;
n++ )
65 nCRC =
crc_table[(nCRC ^ i_pBuf[
n]) & 0xff] ^ (nCRC >> 8);
71 sal_uInt32 nCRC = 0xffffffff;
73 return nCRC ^ 0xffffffff;
78 size_t nOrigSize = o_rOut.size();
82 aStream.zalloc = Z_NULL;
83 aStream.zfree = Z_NULL;
84 aStream.opaque = Z_NULL;
85 aStream.total_out = aStream.total_in = 0;
86 if (Z_OK != deflateInit(&aStream, Z_BEST_COMPRESSION))
88 aStream.avail_in = uInt(i_nLen);
89 aStream.next_in = i_pBuf;
94 aStream.avail_out =
sizeof( aOutBuf );
95 aStream.next_out = aOutBuf;
97 if( deflate( &aStream, Z_FINISH ) == Z_STREAM_ERROR )
99 deflateEnd( &aStream );
101 o_rOut.resize( nOrigSize );
106 sal_uInt32 nCompressedBytes =
sizeof( aOutBuf ) - aStream.avail_out;
107 if( nCompressedBytes )
108 o_rOut.insert( o_rOut.end(), aOutBuf, aOutBuf+nCompressedBytes );
110 }
while( aStream.avail_out == 0 );
113 deflateEnd( &aStream );
115 return sal_uInt32( o_rOut.size() - nOrigSize );
120 static const unsigned char aHeader[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
122 o_rOutputBuf.insert( o_rOutputBuf.end(), aHeader, aHeader +
SAL_N_ELEMENTS(aHeader) );
127 size_t nIndex = sal_uInt32( o_rOutputBuf.size() );
128 o_rOutputBuf.insert( o_rOutputBuf.end(), 4,
Output_t(0) );
129 o_rOutputBuf.push_back( pChunkName[0] );
130 o_rOutputBuf.push_back( pChunkName[1] );
131 o_rOutputBuf.push_back( pChunkName[2] );
132 o_rOutputBuf.push_back( pChunkName[3] );
138 o_rOutputBuf[ i_nIndex ] = (i_nValue & 0xff000000) >> 24;
139 o_rOutputBuf[ i_nIndex+1 ] = (i_nValue & 0x00ff0000) >> 16;
140 o_rOutputBuf[ i_nIndex+2 ] = (i_nValue & 0x0000ff00) >> 8;
141 o_rOutputBuf[ i_nIndex+3 ] = (i_nValue & 0x000000ff);
146 if( nStart+8 > o_rOutputBuf.size() )
150 size_t nLen = o_rOutputBuf.size() - nStart;
151 sal_uInt32 nDataLen = sal_uInt32(nLen)-8;
152 set( nDataLen, o_rOutputBuf, nStart );
155 sal_uInt32 nChunkCRC =
getCRC(
reinterpret_cast<sal_uInt8*
>(&o_rOutputBuf[nStart+4]), nLen-4 );
156 append( nChunkCRC, o_rOutputBuf );
161 size_t nStart =
startChunk(
"IHDR", o_rOutputBuf );
162 append( width, o_rOutputBuf );
163 append( height, o_rOutputBuf );
164 o_rOutputBuf.push_back(
Output_t(depth) );
165 o_rOutputBuf.push_back(
Output_t(colortype) );
166 o_rOutputBuf.push_back( 0 );
167 o_rOutputBuf.push_back( 0 );
168 o_rOutputBuf.push_back( 0 );
174 size_t nStart =
startChunk(
"IEND", o_rOutputBuf );
182 GfxRGB
const & zeroColor,
183 GfxRGB
const & oneColor,
188 appendIHDR( o_rOutputBuf, width, height, 1, 3 );
191 size_t nIdx =
startChunk(
"PLTE", o_rOutputBuf );
193 o_rOutputBuf.push_back(colToByte(zeroColor.r));
194 o_rOutputBuf.push_back(colToByte(zeroColor.g));
195 o_rOutputBuf.push_back(colToByte(zeroColor.b));
196 o_rOutputBuf.push_back(colToByte(oneColor.r));
197 o_rOutputBuf.push_back(colToByte(oneColor.g));
198 o_rOutputBuf.push_back(colToByte(oneColor.b));
206 o_rOutputBuf.push_back( 0xff );
207 o_rOutputBuf.push_back( 0 );
214 int nLineSize = (width + 7)/8;
215 aScanlines.reserve( nLineSize * height + height );
218 for(
int y = 0;
y < height;
y++ )
221 aScanlines.push_back( 0 );
222 for(
int x = 0;
x < nLineSize;
x++ )
223 aScanlines.push_back( str->getChar() );
229 deflateBuffer( aScanlines.data(), aScanlines.size(), o_rOutputBuf );
239 int width,
int height, GfxImageColorMap* colorMap,
241 int maskWidth,
int maskHeight, GfxImageColorMap* maskColorMap )
244 appendIHDR( o_rOutputBuf, width, height, 8, 6 );
247 unsigned char *
p, *pm;
250 std::unique_ptr<ImageStream> imgStr(
253 colorMap->getNumPixelComps(),
254 colorMap->getBits()));
259 aScanlines.reserve( width*height*4 + height );
261 for(
int y=0;
y<height; ++
y)
263 aScanlines.push_back( 0 );
264 p = imgStr->getLine();
265 for(
int x=0;
x<width; ++
x)
267 colorMap->getRGB(
p, &rgb);
268 aScanlines.push_back(colToByte(rgb.r));
269 aScanlines.push_back(colToByte(rgb.g));
270 aScanlines.push_back(colToByte(rgb.b));
271 aScanlines.push_back( 0xff );
273 p +=colorMap->getNumPixelComps();
286 std::unique_ptr<ImageStream> imgStrMask(
287 new ImageStream(maskStr,
289 maskColorMap->getNumPixelComps(),
290 maskColorMap->getBits()));
293 for(
int y = 0;
y < maskHeight; ++
y )
295 pm = imgStrMask->getLine();
296 for(
int x = 0;
x < maskWidth; ++
x )
298 maskColorMap->getGray(pm,&
alpha);
299 pm += maskColorMap->getNumPixelComps();
300 int nIndex = (
y*height/maskHeight) * (width*4+1) +
301 (
x*width/maskWidth)*4 + 1 + 3
311 size_t nIdx =
startChunk(
"IDAT", o_rOutputBuf );
313 deflateBuffer( aScanlines.data(), aScanlines.size(), o_rOutputBuf );
323 int width,
int height, GfxImageColorMap* colorMap,
325 int maskWidth,
int maskHeight,
330 appendIHDR( o_rOutputBuf, width, height, 8, 6 );
335 std::unique_ptr<ImageStream> imgStr(
338 colorMap->getNumPixelComps(),
339 colorMap->getBits()));
344 aScanlines.reserve( width*height*4 + height );
346 for(
int y=0;
y<height; ++
y)
348 aScanlines.push_back( 0 );
349 p = imgStr->getLine();
350 for(
int x=0;
x<width; ++
x)
352 colorMap->getRGB(
p, &rgb);
353 aScanlines.push_back(colToByte(rgb.r));
354 aScanlines.push_back(colToByte(rgb.g));
355 aScanlines.push_back(colToByte(rgb.b));
356 aScanlines.push_back( 0xff );
358 p +=colorMap->getNumPixelComps();
371 std::unique_ptr<ImageStream> imgStrMask(
372 new ImageStream(maskStr, maskWidth, 1, 1));
375 for(
int y = 0;
y < maskHeight; ++
y )
377 for(
int x = 0;
x < maskWidth; ++
x )
379 unsigned char aPixel = 0;
380 imgStrMask->getPixel( &aPixel );
381 int nIndex = (
y*height/maskHeight) * (width*4+1) +
382 (
x*width/maskWidth)*4 + 1 + 3
385 aScanlines[
nIndex ] = aPixel ? 0xff : 0x00;
387 aScanlines[
nIndex ] = aPixel ? 0x00 : 0xff;
395 size_t nIdx =
startChunk(
"IDAT", o_rOutputBuf );
397 deflateBuffer( aScanlines.data(), aScanlines.size(), o_rOutputBuf );
static void appendFileHeader(OutputBuffer &o_rOutputBuf)
static void append(sal_uInt32 i_nValue, OutputBuffer &o_rOutputBuf)
static size_t startChunk(const char *pChunkName, OutputBuffer &o_rOut)
static void initCRCTable()
static void createPng(OutputBuffer &o_rOutputBuf, Stream *str, int width, int height, GfxRGB const &zeroColor, GfxRGB const &oneColor, bool bIsMask)
static bool bCRCTableInit
static void endChunk(size_t nStart, OutputBuffer &o_rOut)
static void set(sal_uInt32 i_nValue, OutputBuffer &o_rOutputBuf, size_t i_nIndex)
static sal_uInt32 getCRC(const sal_uInt8 *i_pBuf, size_t i_nLen)
static void appendIHDR(OutputBuffer &o_rOutputBuf, int width, int height, int depth, int colortype)
static sal_uInt32 deflateBuffer(const Output_t *i_pBuf, size_t i_nLen, OutputBuffer &o_rOut)
static void updateCRC(sal_uInt32 &io_rCRC, const sal_uInt8 *i_pBuf, size_t i_nLen)
static void appendIEND(OutputBuffer &o_rOutputBuf)
static sal_uInt32 crc_table[256]
#define SAL_N_ELEMENTS(arr)
constexpr double alpha[nDetails]
std::vector< Output_t > OutputBuffer