Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
389bf9e1
Kaydet (Commit)
389bf9e1
authored
Mar 24, 2015
tarafından
Tomaž Vajngerl
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
cleanup pngwrite, use const std::unique_ptr for pImpl
Change-Id: I7c9941731789be3553d473d64716484bfceaf8b4
üst
4dfa19d6
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
264 additions
and
212 deletions
+264
-212
pngwrite.hxx
include/vcl/pngwrite.hxx
+5
-10
pngwrite.cxx
vcl/source/gdi/pngwrite.cxx
+259
-202
No files found.
include/vcl/pngwrite.hxx
Dosyayı görüntüle @
389bf9e1
...
@@ -26,33 +26,28 @@
...
@@ -26,33 +26,28 @@
#include <vcl/bitmapex.hxx>
#include <vcl/bitmapex.hxx>
#include <vector>
#include <vector>
// - PNGWriter -
namespace
vcl
namespace
vcl
{
{
class
PNGWriterImpl
;
class
PNGWriterImpl
;
class
VCL_DLLPUBLIC
PNGWriter
class
VCL_DLLPUBLIC
PNGWriter
{
{
PNGWriterImpl
*
mpImpl
;
const
std
::
unique_ptr
<
PNGWriterImpl
>
mpImpl
;
public
:
public
:
explicit
PNGWriter
(
const
BitmapEx
&
,
explicit
PNGWriter
(
const
BitmapEx
&
,
const
css
::
uno
::
Sequence
<
css
::
beans
::
PropertyValue
>*
pFilterData
=
NULL
);
const
::
com
::
sun
::
star
::
uno
::
Sequence
<
::
com
::
sun
::
star
::
beans
::
PropertyValue
>*
pFilterData
=
NULL
);
~
PNGWriter
();
~
PNGWriter
();
bool
Write
(
SvStream
&
rStm
);
bool
Write
(
SvStream
&
rStream
);
// additional method to be able to modify all chunk before they are stored
// additional method to be able to modify all chunk before they are stored
struct
ChunkData
struct
ChunkData
{
{
sal_uInt32
nType
;
sal_uInt32
nType
;
std
::
vector
<
sal_uInt8
>
aData
;
std
::
vector
<
sal_uInt8
>
aData
;
};
};
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>&
GetChunks
();
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>&
GetChunks
();
};
};
}
}
...
...
vcl/source/gdi/pngwrite.cxx
Dosyayı görüntüle @
389bf9e1
...
@@ -47,16 +47,19 @@ class PNGWriterImpl
...
@@ -47,16 +47,19 @@ class PNGWriterImpl
{
{
public
:
public
:
PNGWriterImpl
(
const
BitmapEx
&
BmpEx
,
PNGWriterImpl
(
const
BitmapEx
&
BmpEx
,
const
::
com
::
sun
::
star
::
uno
::
Sequence
<
::
com
::
sun
::
star
::
beans
::
PropertyValue
>*
pFilterData
=
NULL
);
const
css
::
uno
::
Sequence
<
css
::
beans
::
PropertyValue
>*
pFilterData
=
NULL
);
bool
Write
(
SvStream
&
rOStm
);
bool
Write
(
SvStream
&
rOutStream
);
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>&
GetChunks
()
{
return
maChunkSeq
;}
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>&
GetChunks
()
{
return
maChunkSeq
;
}
private
:
private
:
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>
maChunkSeq
;
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>
maChunkSeq
;
sal_Int32
mnCompLevel
;
sal_Int32
mnCompLevel
;
sal_Int32
mnInterlaced
;
sal_Int32
mnInterlaced
;
...
@@ -72,28 +75,29 @@ private:
...
@@ -72,28 +75,29 @@ private:
sal_uInt8
*
mpCurrentScan
;
sal_uInt8
*
mpCurrentScan
;
sal_uLong
mnDeflateInSize
;
sal_uLong
mnDeflateInSize
;
sal_uLong
mnWidth
,
mnHeight
;
sal_uLong
mnWidth
;
sal_uLong
mnHeight
;
sal_uInt8
mnBitsPerPixel
;
sal_uInt8
mnBitsPerPixel
;
sal_uInt8
mnFilterType
;
// 0 oder 4;
sal_uInt8
mnFilterType
;
// 0 oder 4;
sal_uLong
mnBBP
;
// bytes per pixel ( needed for filtering )
sal_uLong
mnBBP
;
// bytes per pixel ( needed for filtering )
bool
mbTrueAlpha
;
bool
mbTrueAlpha
;
sal_uLong
mnCRC
;
sal_uLong
mnCRC
;
void
ImplWritepHYs
(
const
BitmapEx
&
rBitmapEx
);
void
ImplWritepHYs
(
const
BitmapEx
&
rBitmapEx
);
void
ImplWriteIDAT
();
void
ImplWriteIDAT
();
sal_uLong
ImplGetFilter
(
sal_uLong
nY
,
sal_uLong
nXStart
=
0
,
sal_uLong
nXAdd
=
1
);
sal_uLong
ImplGetFilter
(
sal_uLong
nY
,
sal_uLong
nXStart
=
0
,
sal_uLong
nXAdd
=
1
);
void
ImplClearFirstScanline
();
void
ImplClearFirstScanline
();
void
ImplWriteTransparent
();
void
ImplWriteTransparent
();
bool
ImplWriteHeader
();
bool
ImplWriteHeader
();
void
ImplWritePalette
();
void
ImplWritePalette
();
void
ImplOpenChunk
(
sal_uLong
nChunkType
);
void
ImplOpenChunk
(
sal_uLong
nChunkType
);
void
ImplWriteChunk
(
sal_uInt8
nNumb
);
void
ImplWriteChunk
(
sal_uInt8
nNumb
);
void
ImplWriteChunk
(
sal_uInt32
nNumb
);
void
ImplWriteChunk
(
sal_uInt32
nNumb
);
void
ImplWriteChunk
(
unsigned
char
*
pSource
,
sal_uInt32
nDatSize
);
void
ImplWriteChunk
(
unsigned
char
*
pSource
,
sal_uInt32
nDatSize
);
};
};
PNGWriterImpl
::
PNGWriterImpl
(
const
BitmapEx
&
rBmpEx
,
PNGWriterImpl
::
PNGWriterImpl
(
const
BitmapEx
&
rBmpEx
,
const
::
com
::
sun
::
star
::
uno
::
Sequence
<
::
com
::
sun
::
star
::
beans
::
PropertyValue
>*
pFilterData
)
const
css
::
uno
::
Sequence
<
css
::
beans
::
PropertyValue
>*
pFilterData
)
:
mnCompLevel
(
PNG_DEF_COMPRESSION
)
:
mnCompLevel
(
PNG_DEF_COMPRESSION
)
,
mnInterlaced
(
0
)
,
mnInterlaced
(
0
)
,
mnMaxChunkSize
(
0
)
,
mnMaxChunkSize
(
0
)
...
@@ -112,158 +116,174 @@ PNGWriterImpl::PNGWriterImpl( const BitmapEx& rBmpEx,
...
@@ -112,158 +116,174 @@ PNGWriterImpl::PNGWriterImpl( const BitmapEx& rBmpEx,
,
mbTrueAlpha
(
false
)
,
mbTrueAlpha
(
false
)
,
mnCRC
(
0UL
)
,
mnCRC
(
0UL
)
{
{
if
(
!
rBmpEx
.
IsEmpty
()
)
if
(
!
rBmpEx
.
IsEmpty
()
)
{
{
Bitmap
aBmp
(
rBmpEx
.
GetBitmap
()
);
Bitmap
aBmp
(
rBmpEx
.
GetBitmap
()
);
mnInterlaced
=
0
;
// ( aBmp.GetSizePixel().Width() > 128 ) || ( aBmp.GetSizePixel().Height() > 128 ) ? 1 : 0; #i67236#
mnInterlaced
=
0
;
// ( aBmp.GetSizePixel().Width() > 128 ) || ( aBmp.GetSizePixel().Height() > 128 ) ? 1 : 0; #i67236#
// #i67234# defaulting max chunk size to 256kb when using interlace mode
// #i67234# defaulting max chunk size to 256kb when using interlace mode
mnMaxChunkSize
=
mnInterlaced
==
0
?
std
::
numeric_limits
<
sal_uInt32
>::
max
()
:
0x40000
;
mnMaxChunkSize
=
mnInterlaced
==
0
?
std
::
numeric_limits
<
sal_uInt32
>::
max
()
:
0x40000
;
if
(
pFilterData
)
if
(
pFilterData
)
{
{
sal_Int32
i
=
0
;
sal_Int32
i
=
0
;
for
(
i
=
0
;
i
<
pFilterData
->
getLength
();
i
++
)
for
(
i
=
0
;
i
<
pFilterData
->
getLength
();
i
++
)
{
{
if
(
(
*
pFilterData
)[
i
].
Name
==
"Compression"
)
if
(
(
*
pFilterData
)[
i
].
Name
==
"Compression"
)
(
*
pFilterData
)[
i
].
Value
>>=
mnCompLevel
;
(
*
pFilterData
)[
i
].
Value
>>=
mnCompLevel
;
else
if
(
(
*
pFilterData
)[
i
].
Name
==
"Interlaced"
)
else
if
(
(
*
pFilterData
)[
i
].
Name
==
"Interlaced"
)
(
*
pFilterData
)[
i
].
Value
>>=
mnInterlaced
;
(
*
pFilterData
)[
i
].
Value
>>=
mnInterlaced
;
else
if
(
(
*
pFilterData
)[
i
].
Name
==
"MaxChunkSize"
)
else
if
(
(
*
pFilterData
)[
i
].
Name
==
"MaxChunkSize"
)
{
{
sal_Int32
nVal
=
0
;
sal_Int32
nVal
=
0
;
if
(
(
*
pFilterData
)[
i
].
Value
>>=
nVal
)
if
(
(
*
pFilterData
)[
i
].
Value
>>=
nVal
)
mnMaxChunkSize
=
(
sal_uInt32
)
nVal
;
mnMaxChunkSize
=
static_cast
<
sal_uInt32
>
(
nVal
)
;
}
}
}
}
}
}
mnBitsPerPixel
=
(
sal_uInt8
)
aBmp
.
GetBitCount
(
);
mnBitsPerPixel
=
static_cast
<
sal_uInt8
>
(
aBmp
.
GetBitCount
()
);
if
(
rBmpEx
.
IsTransparent
()
)
if
(
rBmpEx
.
IsTransparent
()
)
{
{
if
(
mnBitsPerPixel
<=
8
&&
rBmpEx
.
IsAlpha
()
)
if
(
mnBitsPerPixel
<=
8
&&
rBmpEx
.
IsAlpha
()
)
{
{
aBmp
.
Convert
(
BMP_CONVERSION_24BIT
);
aBmp
.
Convert
(
BMP_CONVERSION_24BIT
);
mnBitsPerPixel
=
24
;
mnBitsPerPixel
=
24
;
}
}
if
(
mnBitsPerPixel
<=
8
)
// transparent palette
if
(
mnBitsPerPixel
<=
8
)
// transparent palette
{
{
aBmp
.
Convert
(
BMP_CONVERSION_8BIT_TRANS
);
aBmp
.
Convert
(
BMP_CONVERSION_8BIT_TRANS
);
aBmp
.
Replace
(
rBmpEx
.
GetMask
(),
BMP_COL_TRANS
);
aBmp
.
Replace
(
rBmpEx
.
GetMask
(),
BMP_COL_TRANS
);
mnBitsPerPixel
=
8
;
mnBitsPerPixel
=
8
;
mpAccess
=
aBmp
.
AcquireReadAccess
();
mpAccess
=
aBmp
.
AcquireReadAccess
();
if
(
mpAccess
)
if
(
mpAccess
)
{
{
if
(
ImplWriteHeader
()
)
if
(
ImplWriteHeader
()
)
{
{
ImplWritepHYs
(
rBmpEx
);
ImplWritepHYs
(
rBmpEx
);
ImplWritePalette
();
ImplWritePalette
();
ImplWriteTransparent
();
ImplWriteTransparent
();
ImplWriteIDAT
();
ImplWriteIDAT
();
}
}
aBmp
.
ReleaseAccess
(
mpAccess
),
mpAccess
=
0
;
aBmp
.
ReleaseAccess
(
mpAccess
);
mpAccess
=
NULL
;
}
}
else
else
{
mbStatus
=
false
;
mbStatus
=
false
;
}
}
}
else
else
{
{
mpAccess
=
aBmp
.
AcquireReadAccess
();
// true RGB with alphachannel
mpAccess
=
aBmp
.
AcquireReadAccess
();
// true RGB with alphachannel
if
(
mpAccess
)
if
(
mpAccess
)
{
{
if
(
(
mbTrueAlpha
=
rBmpEx
.
IsAlpha
()
)
)
if
(
(
mbTrueAlpha
=
rBmpEx
.
IsAlpha
())
)
{
{
AlphaMask
aMask
(
rBmpEx
.
GetAlpha
()
);
AlphaMask
aMask
(
rBmpEx
.
GetAlpha
()
);
mpMaskAccess
=
aMask
.
AcquireReadAccess
();
mpMaskAccess
=
aMask
.
AcquireReadAccess
();
if
(
mpMaskAccess
)
if
(
mpMaskAccess
)
{
{
if
(
ImplWriteHeader
()
)
if
(
ImplWriteHeader
()
)
{
{
ImplWritepHYs
(
rBmpEx
);
ImplWritepHYs
(
rBmpEx
);
ImplWriteIDAT
();
ImplWriteIDAT
();
}
}
aMask
.
ReleaseAccess
(
mpMaskAccess
),
mpMaskAccess
=
0
;
aMask
.
ReleaseAccess
(
mpMaskAccess
);
mpMaskAccess
=
NULL
;
}
}
else
else
{
mbStatus
=
false
;
mbStatus
=
false
;
}
}
}
else
else
{
{
Bitmap
aMask
(
rBmpEx
.
GetMask
()
);
Bitmap
aMask
(
rBmpEx
.
GetMask
()
);
mpMaskAccess
=
aMask
.
AcquireReadAccess
();
mpMaskAccess
=
aMask
.
AcquireReadAccess
();
if
(
mpMaskAccess
)
if
(
mpMaskAccess
)
{
{
if
(
ImplWriteHeader
()
)
if
(
ImplWriteHeader
()
)
{
{
ImplWritepHYs
(
rBmpEx
);
ImplWritepHYs
(
rBmpEx
);
ImplWriteIDAT
();
ImplWriteIDAT
();
}
}
aMask
.
ReleaseAccess
(
mpMaskAccess
),
mpMaskAccess
=
0
;
aMask
.
ReleaseAccess
(
mpMaskAccess
);
mpMaskAccess
=
NULL
;
}
}
else
else
{
mbStatus
=
false
;
mbStatus
=
false
;
}
}
aBmp
.
ReleaseAccess
(
mpAccess
),
mpAccess
=
0
;
}
aBmp
.
ReleaseAccess
(
mpAccess
);
mpAccess
=
NULL
;
}
}
else
else
{
mbStatus
=
false
;
mbStatus
=
false
;
}
}
}
}
}
else
else
{
{
mpAccess
=
aBmp
.
AcquireReadAccess
();
// palette + RGB without alphachannel
mpAccess
=
aBmp
.
AcquireReadAccess
();
// palette + RGB without alphachannel
if
(
mpAccess
)
if
(
mpAccess
)
{
{
if
(
ImplWriteHeader
()
)
if
(
ImplWriteHeader
()
)
{
{
ImplWritepHYs
(
rBmpEx
);
ImplWritepHYs
(
rBmpEx
);
if
(
mpAccess
->
HasPalette
()
)
if
(
mpAccess
->
HasPalette
()
)
ImplWritePalette
();
ImplWritePalette
();
ImplWriteIDAT
();
ImplWriteIDAT
();
}
}
aBmp
.
ReleaseAccess
(
mpAccess
),
mpAccess
=
0
;
aBmp
.
ReleaseAccess
(
mpAccess
);
mpAccess
=
NULL
;
}
}
else
else
{
mbStatus
=
false
;
mbStatus
=
false
;
}
}
if
(
mbStatus
)
}
if
(
mbStatus
)
{
{
ImplOpenChunk
(
PNGCHUNK_IEND
);
// create an IEND chunk
ImplOpenChunk
(
PNGCHUNK_IEND
);
// create an IEND chunk
}
}
}
}
}
}
bool
PNGWriterImpl
::
Write
(
SvStream
&
rOStm
)
bool
PNGWriterImpl
::
Write
(
SvStream
&
rOStm
)
{
{
/* png signature is always an array of 8 bytes */
/* png signature is always an array of 8 bytes */
SvStreamEndian
nOldMode
=
rOStm
.
GetEndian
();
SvStreamEndian
nOldMode
=
rOStm
.
GetEndian
();
rOStm
.
SetEndian
(
SvStreamEndian
::
BIG
);
rOStm
.
SetEndian
(
SvStreamEndian
::
BIG
);
rOStm
.
WriteUInt32
(
0x89504e47
);
rOStm
.
WriteUInt32
(
0x89504e47
);
rOStm
.
WriteUInt32
(
0x0d0a1a0a
);
rOStm
.
WriteUInt32
(
0x0d0a1a0a
);
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>::
iterator
aBeg
(
maChunkSeq
.
begin
()
);
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>::
iterator
aBeg
(
maChunkSeq
.
begin
()
);
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>::
iterator
aEnd
(
maChunkSeq
.
end
()
);
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>::
iterator
aEnd
(
maChunkSeq
.
end
()
);
while
(
aBeg
!=
aEnd
)
while
(
aBeg
!=
aEnd
)
{
{
sal_uInt32
nType
=
aBeg
->
nType
;
sal_uInt32
nType
=
aBeg
->
nType
;
#if defined(__LITTLEENDIAN) || defined(OSL_LITENDIAN)
#if defined(__LITTLEENDIAN) || defined(OSL_LITENDIAN)
nType
=
OSL_SWAPDWORD
(
nType
);
nType
=
OSL_SWAPDWORD
(
nType
);
#endif
#endif
sal_uInt32
nCRC
=
rtl_crc32
(
0
,
&
nType
,
4
);
sal_uInt32
nCRC
=
rtl_crc32
(
0
,
&
nType
,
4
);
sal_uInt32
nDataSize
=
aBeg
->
aData
.
size
();
sal_uInt32
nDataSize
=
aBeg
->
aData
.
size
();
if
(
nDataSize
)
if
(
nDataSize
)
nCRC
=
rtl_crc32
(
nCRC
,
&
aBeg
->
aData
[
0
],
nDataSize
);
nCRC
=
rtl_crc32
(
nCRC
,
&
aBeg
->
aData
[
0
],
nDataSize
);
rOStm
.
WriteUInt32
(
nDataSize
)
rOStm
.
WriteUInt32
(
nDataSize
);
.
WriteUInt32
(
aBeg
->
nType
);
rOStm
.
WriteUInt32
(
aBeg
->
nType
);
if
(
nDataSize
)
if
(
nDataSize
)
rOStm
.
Write
(
&
aBeg
->
aData
[
0
],
nDataSize
);
rOStm
.
Write
(
&
aBeg
->
aData
[
0
],
nDataSize
);
rOStm
.
WriteUInt32
(
nCRC
);
rOStm
.
WriteUInt32
(
nCRC
);
++
aBeg
;
++
aBeg
;
}
}
rOStm
.
SetEndian
(
nOldMode
);
rOStm
.
SetEndian
(
nOldMode
);
return
mbStatus
;
return
mbStatus
;
}
}
...
@@ -271,155 +291,177 @@ bool PNGWriterImpl::Write( SvStream& rOStm )
...
@@ -271,155 +291,177 @@ bool PNGWriterImpl::Write( SvStream& rOStm )
bool
PNGWriterImpl
::
ImplWriteHeader
()
bool
PNGWriterImpl
::
ImplWriteHeader
()
{
{
ImplOpenChunk
(
PNGCHUNK_IHDR
);
ImplOpenChunk
(
PNGCHUNK_IHDR
);
ImplWriteChunk
(
sal_uInt32
(
mnWidth
=
mpAccess
->
Width
()
)
);
ImplWriteChunk
(
sal_uInt32
(
mnWidth
=
mpAccess
->
Width
())
);
ImplWriteChunk
(
sal_uInt32
(
mnHeight
=
mpAccess
->
Height
()
)
);
ImplWriteChunk
(
sal_uInt32
(
mnHeight
=
mpAccess
->
Height
())
);
if
(
mnWidth
&&
mnHeight
&&
mnBitsPerPixel
&&
mbStatus
)
if
(
mnWidth
&&
mnHeight
&&
mnBitsPerPixel
&&
mbStatus
)
{
{
sal_uInt8
nBitDepth
=
mnBitsPerPixel
;
sal_uInt8
nBitDepth
=
mnBitsPerPixel
;
if
(
mnBitsPerPixel
<=
8
)
if
(
mnBitsPerPixel
<=
8
)
mnFilterType
=
0
;
mnFilterType
=
0
;
else
else
mnFilterType
=
4
;
mnFilterType
=
4
;
sal_uInt8
nColorType
=
2
;
// colortype:
sal_uInt8
nColorType
=
2
;
// colortype:
// bit 0 -> palette is used
// bit 0 -> palette is used
if
(
mpAccess
->
HasPalette
()
)
// bit 1 -> color is used
if
(
mpAccess
->
HasPalette
())
// bit 1 -> color is used
nColorType
|=
1
;
// bit 2 -> alpha channel is used
nColorType
|=
1
;
// bit 2 -> alpha channel is used
else
else
nBitDepth
/=
3
;
nBitDepth
/=
3
;
if
(
mpMaskAccess
)
if
(
mpMaskAccess
)
nColorType
|=
4
;
nColorType
|=
4
;
ImplWriteChunk
(
nBitDepth
);
ImplWriteChunk
(
nBitDepth
);
ImplWriteChunk
(
nColorType
);
// colortype
ImplWriteChunk
(
nColorType
);
// colortype
ImplWriteChunk
(
(
sal_uInt8
)
0
);
// compression type
ImplWriteChunk
(
static_cast
<
sal_uInt8
>
(
0
));
// compression type
ImplWriteChunk
(
(
sal_uInt8
)
0
);
// filter type - is not supported in this version
ImplWriteChunk
(
static_cast
<
sal_uInt8
>
(
0
));
// filter type - is not supported in this version
ImplWriteChunk
(
(
sal_uInt8
)
mnInterlaced
);
// interlace type
ImplWriteChunk
(
static_cast
<
sal_uInt8
>
(
mnInterlaced
));
// interlace type
}
}
else
else
{
mbStatus
=
false
;
mbStatus
=
false
;
}
return
mbStatus
;
return
mbStatus
;
}
}
void
PNGWriterImpl
::
ImplWritePalette
()
void
PNGWriterImpl
::
ImplWritePalette
()
{
{
const
sal_uLong
nCount
=
mpAccess
->
GetPaletteEntryCount
();
const
sal_uLong
nCount
=
mpAccess
->
GetPaletteEntryCount
();
boost
::
scoped_array
<
sal_uInt8
>
pTempBuf
(
new
sal_uInt8
[
nCount
*
3
]);
boost
::
scoped_array
<
sal_uInt8
>
pTempBuf
(
new
sal_uInt8
[
nCount
*
3
]);
sal_uInt8
*
pTmp
=
pTempBuf
.
get
();
sal_uInt8
*
pTmp
=
pTempBuf
.
get
();
ImplOpenChunk
(
PNGCHUNK_PLTE
);
ImplOpenChunk
(
PNGCHUNK_PLTE
);
for
(
sal_uInt16
i
=
0
;
i
<
nCount
;
i
++
)
for
(
sal_uInt16
i
=
0
;
i
<
nCount
;
i
++
)
{
{
const
BitmapColor
&
rColor
=
mpAccess
->
GetPaletteColor
(
i
);
const
BitmapColor
&
rColor
=
mpAccess
->
GetPaletteColor
(
i
);
*
pTmp
++
=
rColor
.
GetRed
();
*
pTmp
++
=
rColor
.
GetRed
();
*
pTmp
++
=
rColor
.
GetGreen
();
*
pTmp
++
=
rColor
.
GetGreen
();
*
pTmp
++
=
rColor
.
GetBlue
();
*
pTmp
++
=
rColor
.
GetBlue
();
}
}
ImplWriteChunk
(
pTempBuf
.
get
(),
nCount
*
3
);
ImplWriteChunk
(
pTempBuf
.
get
(),
nCount
*
3
);
}
}
void
PNGWriterImpl
::
ImplWriteTransparent
()
void
PNGWriterImpl
::
ImplWriteTransparent
()
{
{
const
sal_uLong
nTransIndex
=
mpAccess
->
GetBestPaletteIndex
(
BMP_COL_TRANS
);
const
sal_uLong
nTransIndex
=
mpAccess
->
GetBestPaletteIndex
(
BMP_COL_TRANS
);
ImplOpenChunk
(
PNGCHUNK_tRNS
);
ImplOpenChunk
(
PNGCHUNK_tRNS
);
for
(
sal_uLong
n
=
0UL
;
n
<=
nTransIndex
;
n
++
)
for
(
sal_uLong
n
=
0UL
;
n
<=
nTransIndex
;
n
++
)
ImplWriteChunk
(
(
nTransIndex
==
n
)
?
(
sal_uInt8
)
0x0
:
(
sal_uInt8
)
0xff
);
{
ImplWriteChunk
((
nTransIndex
==
n
)
?
static_cast
<
sal_uInt8
>
(
0x0
)
:
static_cast
<
sal_uInt8
>
(
0xff
));
}
}
}
void
PNGWriterImpl
::
ImplWritepHYs
(
const
BitmapEx
&
rBmpEx
)
void
PNGWriterImpl
::
ImplWritepHYs
(
const
BitmapEx
&
rBmpEx
)
{
{
if
(
rBmpEx
.
GetPrefMapMode
()
==
MAP_100TH_MM
)
if
(
rBmpEx
.
GetPrefMapMode
()
==
MAP_100TH_MM
)
{
{
Size
aPrefSize
(
rBmpEx
.
GetPrefSize
()
);
Size
aPrefSize
(
rBmpEx
.
GetPrefSize
());
if
(
aPrefSize
.
Width
()
&&
aPrefSize
.
Height
()
&&
mnWidth
&&
mnHeight
)
if
(
aPrefSize
.
Width
()
&&
aPrefSize
.
Height
()
&&
mnWidth
&&
mnHeight
)
{
{
ImplOpenChunk
(
PNGCHUNK_pHYs
);
ImplOpenChunk
(
PNGCHUNK_pHYs
);
sal_uInt8
nMapUnit
=
1
;
sal_uInt8
nMapUnit
=
1
;
sal_uInt32
nPrefSizeX
=
(
sal_uInt32
)(
(
double
)
100000.0
/
(
(
double
)
aPrefSize
.
Width
()
/
mnWidth
)
+
0.5
);
sal_uInt32
nPrefSizeX
=
static_cast
<
sal_uInt32
>
(
100000.0
/
(
static_cast
<
double
>
(
aPrefSize
.
Width
())
/
mnWidth
)
+
0.5
);
sal_uInt32
nPrefSizeY
=
(
sal_uInt32
)(
(
double
)
100000.0
/
(
(
double
)
aPrefSize
.
Height
()
/
mnHeight
)
+
0.5
);
sal_uInt32
nPrefSizeY
=
static_cast
<
sal_uInt32
>
(
100000.0
/
(
static_cast
<
double
>
(
aPrefSize
.
Height
())
/
mnHeight
)
+
0.5
);
ImplWriteChunk
(
nPrefSizeX
);
ImplWriteChunk
(
nPrefSizeX
);
ImplWriteChunk
(
nPrefSizeY
);
ImplWriteChunk
(
nPrefSizeY
);
ImplWriteChunk
(
nMapUnit
);
ImplWriteChunk
(
nMapUnit
);
}
}
}
}
}
}
void
PNGWriterImpl
::
ImplWriteIDAT
()
void
PNGWriterImpl
::
ImplWriteIDAT
()
{
{
mnDeflateInSize
=
mnBitsPerPixel
;
mnDeflateInSize
=
mnBitsPerPixel
;
if
(
mpMaskAccess
)
if
(
mpMaskAccess
)
mnDeflateInSize
+=
8
;
mnDeflateInSize
+=
8
;
mnBBP
=
(
mnDeflateInSize
+
7
)
>>
3
;
mnBBP
=
(
mnDeflateInSize
+
7
)
>>
3
;
mnDeflateInSize
=
mnBBP
*
mnWidth
+
1
;
mnDeflateInSize
=
mnBBP
*
mnWidth
+
1
;
mpDeflateInBuf
=
new
sal_uInt8
[
mnDeflateInSize
];
mpDeflateInBuf
=
new
sal_uInt8
[
mnDeflateInSize
];
if
(
mnFilterType
)
// using filter type 4 we need memory for the scanline 3 times
if
(
mnFilterType
)
// using filter type 4 we need memory for the scanline 3 times
{
{
mpPreviousScan
=
new
sal_uInt8
[
mnDeflateInSize
];
mpPreviousScan
=
new
sal_uInt8
[
mnDeflateInSize
];
mpCurrentScan
=
new
sal_uInt8
[
mnDeflateInSize
];
mpCurrentScan
=
new
sal_uInt8
[
mnDeflateInSize
];
ImplClearFirstScanline
();
ImplClearFirstScanline
();
}
}
mpZCodec
.
BeginCompression
(
mnCompLevel
,
true
);
mpZCodec
.
BeginCompression
(
mnCompLevel
,
true
);
mpZCodec
.
SetCRC
(
mnCRC
);
mpZCodec
.
SetCRC
(
mnCRC
);
SvMemoryStream
aOStm
;
SvMemoryStream
aOStm
;
if
(
mnInterlaced
==
0
)
if
(
mnInterlaced
==
0
)
{
for
(
sal_uLong
nY
=
0
;
nY
<
mnHeight
;
nY
++
)
{
{
for
(
sal_uLong
nY
=
0
;
nY
<
mnHeight
;
nY
++
)
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
));
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
)
);
}
}
}
else
else
{
{
// interlace mode
// interlace mode
sal_uLong
nY
;
sal_uLong
nY
;
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
8
)
// pass 1
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
8
)
// pass 1
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
8
)
);
{
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
8
));
}
ImplClearFirstScanline
();
ImplClearFirstScanline
();
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
8
)
// pass 2
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
8
)
// pass 2
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
4
,
8
)
);
{
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
4
,
8
));
}
ImplClearFirstScanline
();
ImplClearFirstScanline
();
if
(
mnHeight
>=
5
)
// pass 3
if
(
mnHeight
>=
5
)
// pass 3
{
for
(
nY
=
4
;
nY
<
mnHeight
;
nY
+=
8
)
{
{
for
(
nY
=
4
;
nY
<
mnHeight
;
nY
+=
8
)
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
4
));
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
4
)
);
}
ImplClearFirstScanline
();
ImplClearFirstScanline
();
}
}
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
4
)
// pass 4
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
4
)
// pass 4
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
2
,
4
)
);
{
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
2
,
4
));
}
ImplClearFirstScanline
();
ImplClearFirstScanline
();
if
(
mnHeight
>=
3
)
// pass 5
if
(
mnHeight
>=
3
)
// pass 5
{
for
(
nY
=
2
;
nY
<
mnHeight
;
nY
+=
4
)
{
{
for
(
nY
=
2
;
nY
<
mnHeight
;
nY
+=
4
)
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
2
));
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
2
)
);
}
ImplClearFirstScanline
();
ImplClearFirstScanline
();
}
}
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
2
)
// pass 6
for
(
nY
=
0
;
nY
<
mnHeight
;
nY
+=
2
)
// pass 6
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
1
,
2
)
);
{
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
1
,
2
));
}
ImplClearFirstScanline
();
ImplClearFirstScanline
();
if
(
mnHeight
>=
2
)
// pass 7
if
(
mnHeight
>=
2
)
// pass 7
{
{
for
(
nY
=
1
;
nY
<
mnHeight
;
nY
+=
2
)
for
(
nY
=
1
;
nY
<
mnHeight
;
nY
+=
2
)
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
1
)
);
{
mpZCodec
.
Write
(
aOStm
,
mpDeflateInBuf
,
ImplGetFilter
(
nY
,
0
,
1
));
}
}
}
}
}
mpZCodec
.
EndCompression
();
mpZCodec
.
EndCompression
();
mnCRC
=
mpZCodec
.
GetCRC
();
mnCRC
=
mpZCodec
.
GetCRC
();
if
(
mnFilterType
)
// using filter type 4 we need memory for the scanline 3 times
if
(
mnFilterType
)
// using filter type 4 we need memory for the scanline 3 times
{
{
delete
[]
mpCurrentScan
;
delete
[]
mpCurrentScan
;
delete
[]
mpPreviousScan
;
delete
[]
mpPreviousScan
;
...
@@ -428,11 +470,11 @@ void PNGWriterImpl::ImplWriteIDAT ()
...
@@ -428,11 +470,11 @@ void PNGWriterImpl::ImplWriteIDAT ()
sal_uInt32
nIDATSize
=
aOStm
.
Tell
();
sal_uInt32
nIDATSize
=
aOStm
.
Tell
();
sal_uInt32
nBytes
,
nBytesToWrite
=
nIDATSize
;
sal_uInt32
nBytes
,
nBytesToWrite
=
nIDATSize
;
while
(
nBytesToWrite
)
while
(
nBytesToWrite
)
{
{
nBytes
=
nBytesToWrite
<=
mnMaxChunkSize
?
nBytesToWrite
:
mnMaxChunkSize
;
nBytes
=
nBytesToWrite
<=
mnMaxChunkSize
?
nBytesToWrite
:
mnMaxChunkSize
;
ImplOpenChunk
(
PNGCHUNK_IDAT
);
ImplOpenChunk
(
PNGCHUNK_IDAT
);
ImplWriteChunk
(
(
unsigned
char
*
)
aOStm
.
GetData
()
+
(
nIDATSize
-
nBytesToWrite
),
nBytes
);
ImplWriteChunk
(
(
unsigned
char
*
)
aOStm
.
GetData
()
+
(
nIDATSize
-
nBytesToWrite
),
nBytes
);
nBytesToWrite
-=
nBytes
;
nBytesToWrite
-=
nBytes
;
}
}
}
}
...
@@ -441,59 +483,63 @@ void PNGWriterImpl::ImplWriteIDAT ()
...
@@ -441,59 +483,63 @@ void PNGWriterImpl::ImplWriteIDAT ()
// appends to the currently used pass
// appends to the currently used pass
// the complete size of scanline will be returned - in interlace mode zero is possible!
// the complete size of scanline will be returned - in interlace mode zero is possible!
sal_uLong
PNGWriterImpl
::
ImplGetFilter
(
sal_uLong
nY
,
sal_uLong
nXStart
,
sal_uLong
nXAdd
)
sal_uLong
PNGWriterImpl
::
ImplGetFilter
(
sal_uLong
nY
,
sal_uLong
nXStart
,
sal_uLong
nXAdd
)
{
{
sal_uInt8
*
pDest
;
sal_uInt8
*
pDest
;
if
(
mnFilterType
)
if
(
mnFilterType
)
pDest
=
mpCurrentScan
;
pDest
=
mpCurrentScan
;
else
else
pDest
=
mpDeflateInBuf
;
pDest
=
mpDeflateInBuf
;
if
(
nXStart
<
mnWidth
)
if
(
nXStart
<
mnWidth
)
{
{
*
pDest
++
=
mnFilterType
;
// in this version the filter type is either 0 or 4
*
pDest
++
=
mnFilterType
;
// in this version the filter type is either 0 or 4
if
(
mpAccess
->
HasPalette
()
)
// alphachannel is not allowed by pictures including palette entries
if
(
mpAccess
->
HasPalette
())
// alphachannel is not allowed by pictures including palette entries
{
{
switch
(
mnBitsPerPixel
)
switch
(
mnBitsPerPixel
)
{
{
case
(
1
)
:
case
1
:
{
{
sal_uLong
nX
,
nXIndex
;
sal_uLong
nX
,
nXIndex
;
for
(
nX
=
nXStart
,
nXIndex
=
0
;
nX
<
mnWidth
;
nX
+=
nXAdd
,
nXIndex
++
)
for
(
nX
=
nXStart
,
nXIndex
=
0
;
nX
<
mnWidth
;
nX
+=
nXAdd
,
nXIndex
++
)
{
{
sal_uLong
nShift
=
(
nXIndex
&
7
)
^
7
;
sal_uLong
nShift
=
(
nXIndex
&
7
)
^
7
;
if
(
nShift
==
7
)
if
(
nShift
==
7
)
*
pDest
=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
nShift
;
*
pDest
=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
nShift
;
else
if
(
nShift
==
0
)
else
if
(
nShift
==
0
)
*
pDest
++
|=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
nShift
;
*
pDest
++
|=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
nShift
;
else
else
*
pDest
|=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
nShift
;
*
pDest
|=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
nShift
;
}
if
(
(
nXIndex
&
7
)
!=
0
)
pDest
++
;
// byte is not completely used, so the bufferpointer is to correct
}
}
if
(
(
nXIndex
&
7
)
!=
0
)
pDest
++
;
// byte is not completely used, so the
}
// bufferpointer is to correct
break
;
break
;
case
(
4
)
:
case
4
:
{
{
sal_uLong
nX
,
nXIndex
;
sal_uLong
nX
,
nXIndex
;
for
(
nX
=
nXStart
,
nXIndex
=
0
;
nX
<
mnWidth
;
nX
+=
nXAdd
,
nXIndex
++
)
for
(
nX
=
nXStart
,
nXIndex
=
0
;
nX
<
mnWidth
;
nX
+=
nXAdd
,
nXIndex
++
)
{
{
if
(
nXIndex
&
1
)
if
(
nXIndex
&
1
)
*
pDest
++
|=
mpAccess
->
GetPixelIndex
(
nY
,
nX
);
*
pDest
++
|=
mpAccess
->
GetPixelIndex
(
nY
,
nX
);
else
else
*
pDest
=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
4
;
*
pDest
=
mpAccess
->
GetPixelIndex
(
nY
,
nX
)
<<
4
;
}
}
if
(
nXIndex
&
1
)
pDest
++
;
if
(
nXIndex
&
1
)
pDest
++
;
}
}
break
;
break
;
case
(
8
):
case
8
:
{
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
{
{
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
*
pDest
++
=
mpAccess
->
GetPixelIndex
(
nY
,
nX
);
*
pDest
++
=
mpAccess
->
GetPixelIndex
(
nY
,
nX
);
}
}
}
break
;
break
;
default
:
default
:
...
@@ -503,31 +549,31 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
...
@@ -503,31 +549,31 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
}
}
else
else
{
{
if
(
mpMaskAccess
)
// mpMaskAccess != NULL -> alphachannel is to create
if
(
mpMaskAccess
)
// mpMaskAccess != NULL -> alphachannel is to create
{
{
if
(
mbTrueAlpha
)
if
(
mbTrueAlpha
)
{
{
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
{
{
const
BitmapColor
&
rColor
=
mpAccess
->
GetPixel
(
nY
,
nX
);
const
BitmapColor
&
rColor
=
mpAccess
->
GetPixel
(
nY
,
nX
);
*
pDest
++
=
rColor
.
GetRed
();
*
pDest
++
=
rColor
.
GetRed
();
*
pDest
++
=
rColor
.
GetGreen
();
*
pDest
++
=
rColor
.
GetGreen
();
*
pDest
++
=
rColor
.
GetBlue
();
*
pDest
++
=
rColor
.
GetBlue
();
*
pDest
++
=
255
-
mpMaskAccess
->
GetPixelIndex
(
nY
,
nX
);
*
pDest
++
=
255
-
mpMaskAccess
->
GetPixelIndex
(
nY
,
nX
);
}
}
}
}
else
else
{
{
const
BitmapColor
aTrans
(
mpMaskAccess
->
GetBestMatchingColor
(
Color
(
COL_WHITE
)
)
);
const
BitmapColor
aTrans
(
mpMaskAccess
->
GetBestMatchingColor
(
Color
(
COL_WHITE
))
);
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
{
{
const
BitmapColor
&
rColor
=
mpAccess
->
GetPixel
(
nY
,
nX
);
const
BitmapColor
&
rColor
=
mpAccess
->
GetPixel
(
nY
,
nX
);
*
pDest
++
=
rColor
.
GetRed
();
*
pDest
++
=
rColor
.
GetRed
();
*
pDest
++
=
rColor
.
GetGreen
();
*
pDest
++
=
rColor
.
GetGreen
();
*
pDest
++
=
rColor
.
GetBlue
();
*
pDest
++
=
rColor
.
GetBlue
();
if
(
mpMaskAccess
->
GetPixel
(
nY
,
nX
)
==
aTrans
)
if
(
mpMaskAccess
->
GetPixel
(
nY
,
nX
)
==
aTrans
)
*
pDest
++
=
0
;
*
pDest
++
=
0
;
else
else
*
pDest
++
=
0xff
;
*
pDest
++
=
0xff
;
...
@@ -536,9 +582,9 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
...
@@ -536,9 +582,9 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
}
}
else
else
{
{
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
for
(
sal_uLong
nX
=
nXStart
;
nX
<
mnWidth
;
nX
+=
nXAdd
)
{
{
const
BitmapColor
&
rColor
=
mpAccess
->
GetPixel
(
nY
,
nX
);
const
BitmapColor
&
rColor
=
mpAccess
->
GetPixel
(
nY
,
nX
);
*
pDest
++
=
rColor
.
GetRed
();
*
pDest
++
=
rColor
.
GetRed
();
*
pDest
++
=
rColor
.
GetGreen
();
*
pDest
++
=
rColor
.
GetGreen
();
*
pDest
++
=
rColor
.
GetBlue
();
*
pDest
++
=
rColor
.
GetBlue
();
...
@@ -547,7 +593,7 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
...
@@ -547,7 +593,7 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
}
}
}
}
// filter type4 ( PAETH ) will be used only for 24bit graphics
// filter type4 ( PAETH ) will be used only for 24bit graphics
if
(
mnFilterType
)
if
(
mnFilterType
)
{
{
mnDeflateInSize
=
pDest
-
mpCurrentScan
;
mnDeflateInSize
=
pDest
-
mpCurrentScan
;
pDest
=
mpDeflateInBuf
;
pDest
=
mpDeflateInBuf
;
...
@@ -561,96 +607,107 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
...
@@ -561,96 +607,107 @@ sal_uLong PNGWriterImpl::ImplGetFilter ( sal_uLong nY, sal_uLong nXStart, sal_uL
sal_uInt8
*
p3
=
mpPreviousScan
;
// upper pixel
sal_uInt8
*
p3
=
mpPreviousScan
;
// upper pixel
sal_uInt8
*
p4
=
p3
-
mnBBP
;
// upperleft Pixel;
sal_uInt8
*
p4
=
p3
-
mnBBP
;
// upperleft Pixel;
while
(
pDest
<
mpDeflateInBuf
+
mnDeflateInSize
)
while
(
pDest
<
mpDeflateInBuf
+
mnDeflateInSize
)
{
{
nb
=
*
p3
++
;
nb
=
*
p3
++
;
if
(
p2
>=
mpCurrentScan
+
1
)
if
(
p2
>=
mpCurrentScan
+
1
)
{
{
na
=
*
p2
;
na
=
*
p2
;
nc
=
*
p4
;
nc
=
*
p4
;
}
}
else
else
{
na
=
nc
=
0
;
na
=
nc
=
0
;
}
np
=
na
+
nb
;
np
=
na
+
nb
;
np
-=
nc
;
np
-=
nc
;
npa
=
np
-
na
;
npa
=
np
-
na
;
npb
=
np
-
nb
;
npb
=
np
-
nb
;
npc
=
np
-
nc
;
npc
=
np
-
nc
;
if
(
npa
<
0
)
if
(
npa
<
0
)
npa
=-
npa
;
npa
=-
npa
;
if
(
npb
<
0
)
if
(
npb
<
0
)
npb
=-
npb
;
npb
=-
npb
;
if
(
npc
<
0
)
if
(
npc
<
0
)
npc
=-
npc
;
npc
=-
npc
;
if
(
(
npa
<=
npb
)
&&
(
npa
<=
npc
)
)
*
pDest
++
=
*
p1
++
-
(
sal_uInt8
)
na
;
else
if
(
npb
<=
npc
)
*
pDest
++
=
*
p1
++
-
(
sal_uInt8
)
nb
;
if
(
npa
<=
npb
&&
npa
<=
npc
)
else
*
pDest
++
=
*
p1
++
-
(
sal_uInt8
)
nc
;
*
pDest
++
=
*
p1
++
-
static_cast
<
sal_uInt8
>
(
na
);
else
if
(
npb
<=
npc
)
*
pDest
++
=
*
p1
++
-
static_cast
<
sal_uInt8
>
(
nb
);
else
*
pDest
++
=
*
p1
++
-
static_cast
<
sal_uInt8
>
(
nc
);
p4
++
;
p4
++
;
p2
++
;
p2
++
;
}
}
for
(
long
i
=
0
;
i
<
(
long
)(
mnDeflateInSize
-
1
);
i
++
)
for
(
long
i
=
0
;
i
<
static_cast
<
long
>
(
mnDeflateInSize
-
1
);
i
++
)
mpPreviousScan
[
i
]
=
mpCurrentScan
[
i
+
1
];
{
mpPreviousScan
[
i
]
=
mpCurrentScan
[
i
+
1
];
}
}
}
else
else
{
mnDeflateInSize
=
pDest
-
mpDeflateInBuf
;
mnDeflateInSize
=
pDest
-
mpDeflateInBuf
;
}
return
mnDeflateInSize
;
return
mnDeflateInSize
;
}
}
void
PNGWriterImpl
::
ImplClearFirstScanline
()
void
PNGWriterImpl
::
ImplClearFirstScanline
()
{
{
if
(
mnFilterType
)
if
(
mnFilterType
)
memset
(
mpPreviousScan
,
0
,
mnDeflateInSize
);
memset
(
mpPreviousScan
,
0
,
mnDeflateInSize
);
}
}
void
PNGWriterImpl
::
ImplOpenChunk
(
sal_uLong
nChunkType
)
void
PNGWriterImpl
::
ImplOpenChunk
(
sal_uLong
nChunkType
)
{
{
maChunkSeq
.
resize
(
maChunkSeq
.
size
()
+
1
);
maChunkSeq
.
resize
(
maChunkSeq
.
size
()
+
1
);
maChunkSeq
.
back
().
nType
=
nChunkType
;
maChunkSeq
.
back
().
nType
=
nChunkType
;
}
}
void
PNGWriterImpl
::
ImplWriteChunk
(
sal_uInt8
nSource
)
void
PNGWriterImpl
::
ImplWriteChunk
(
sal_uInt8
nSource
)
{
{
maChunkSeq
.
back
().
aData
.
push_back
(
nSource
);
maChunkSeq
.
back
().
aData
.
push_back
(
nSource
);
}
}
void
PNGWriterImpl
::
ImplWriteChunk
(
sal_uInt32
nSource
)
void
PNGWriterImpl
::
ImplWriteChunk
(
sal_uInt32
nSource
)
{
{
vcl
::
PNGWriter
::
ChunkData
&
rChunkData
=
maChunkSeq
.
back
();
vcl
::
PNGWriter
::
ChunkData
&
rChunkData
=
maChunkSeq
.
back
();
rChunkData
.
aData
.
push_back
(
(
sal_uInt8
)(
nSource
>>
24
)
);
rChunkData
.
aData
.
push_back
(
static_cast
<
sal_uInt8
>
(
nSource
>>
24
)
);
rChunkData
.
aData
.
push_back
(
(
sal_uInt8
)(
nSource
>>
16
)
);
rChunkData
.
aData
.
push_back
(
static_cast
<
sal_uInt8
>
(
nSource
>>
16
)
);
rChunkData
.
aData
.
push_back
(
(
sal_uInt8
)(
nSource
>>
8
)
);
rChunkData
.
aData
.
push_back
(
static_cast
<
sal_uInt8
>
(
nSource
>>
8
)
);
rChunkData
.
aData
.
push_back
(
(
sal_uInt8
)(
nSource
)
);
rChunkData
.
aData
.
push_back
(
static_cast
<
sal_uInt8
>
(
nSource
)
);
}
}
void
PNGWriterImpl
::
ImplWriteChunk
(
unsigned
char
*
pSource
,
sal_uInt32
nDatSize
)
void
PNGWriterImpl
::
ImplWriteChunk
(
unsigned
char
*
pSource
,
sal_uInt32
nDatSize
)
{
{
if
(
nDatSize
)
if
(
nDatSize
)
{
{
vcl
::
PNGWriter
::
ChunkData
&
rChunkData
=
maChunkSeq
.
back
();
vcl
::
PNGWriter
::
ChunkData
&
rChunkData
=
maChunkSeq
.
back
();
sal_uInt32
nSize
=
rChunkData
.
aData
.
size
();
sal_uInt32
nSize
=
rChunkData
.
aData
.
size
();
rChunkData
.
aData
.
resize
(
nSize
+
nDatSize
);
rChunkData
.
aData
.
resize
(
nSize
+
nDatSize
);
memcpy
(
&
rChunkData
.
aData
[
nSize
],
pSource
,
nDatSize
);
memcpy
(
&
rChunkData
.
aData
[
nSize
],
pSource
,
nDatSize
);
}
}
}
}
PNGWriter
::
PNGWriter
(
const
BitmapEx
&
rBmpEx
,
PNGWriter
::
PNGWriter
(
const
BitmapEx
&
rBmpEx
,
const
::
com
::
sun
::
star
::
uno
::
Sequence
<
::
com
::
sun
::
star
::
beans
::
PropertyValue
>*
pFilterData
)
:
const
css
::
uno
::
Sequence
<
css
::
beans
::
PropertyValue
>*
pFilterData
)
mpImpl
(
new
::
vcl
::
PNGWriterImpl
(
rBmpEx
,
pFilterData
)
)
:
mpImpl
(
new
vcl
::
PNGWriterImpl
(
rBmpEx
,
pFilterData
)
)
{
{
}
}
PNGWriter
::~
PNGWriter
()
PNGWriter
::~
PNGWriter
()
{
{
delete
mpImpl
;
}
}
bool
PNGWriter
::
Write
(
SvStream
&
rIStm
)
bool
PNGWriter
::
Write
(
SvStream
&
rStream
)
{
{
return
mpImpl
->
Write
(
rIStm
);
return
mpImpl
->
Write
(
rStream
);
}
}
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>&
PNGWriter
::
GetChunks
()
std
::
vector
<
vcl
::
PNGWriter
::
ChunkData
>&
PNGWriter
::
GetChunks
()
{
{
return
mpImpl
->
GetChunks
();
return
mpImpl
->
GetChunks
();
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment