LibreOffice Module vcl (master) 1
etiff.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <tools/stream.hxx>
22#include <vcl/graph.hxx>
23#include <vcl/outdev.hxx>
26#include <com/sun/star/task/XStatusIndicator.hpp>
27#include <filter/TiffWriter.hxx>
28
29#define NewSubfileType 254
30#define ImageWidth 256
31#define ImageLength 257
32#define BitsPerSample 258
33#define Compression 259
34#define PhotometricInterpretation 262
35#define StripOffsets 273
36#define SamplesPerPixel 277
37#define RowsPerStrip 278
38#define StripByteCounts 279
39#define XResolution 282
40#define YResolution 283
41#define PlanarConfiguration 284
42#define ResolutionUnit 296
43#define ColorMap 320
44
45namespace {
46
47struct TIFFLZWCTreeNode
48{
49
50 TIFFLZWCTreeNode* pBrother; // next node with the same father
51 TIFFLZWCTreeNode* pFirstChild; // first son
52 sal_uInt16 nCode; // The code for the string of pixel values, which arises if... <missing comment>
53 sal_uInt16 nValue; // pixel value
54};
55
56
57class TIFFWriter
58{
59private:
60
61 SvStream& m_rOStm;
62 sal_uInt32 mnStreamOfs;
63
64 bool mbStatus;
65 BitmapReadAccess* mpAcc;
66
67 sal_uInt32 mnWidth, mnHeight, mnColors;
68 sal_uInt32 mnCurAllPictHeight;
69 sal_uInt32 mnSumOfAllPictHeight;
70 sal_uInt32 mnBitsPerPixel;
71 sal_uInt32 mnLastPercent;
72
73 sal_uInt32 mnLatestIfdPos;
74 sal_uInt16 mnTagCount; // number of tags already written
75 sal_uInt32 mnCurrentTagCountPos; // offset to the position where the current
76 // tag count is to insert
77
78 sal_uInt32 mnXResPos; // if != 0 this DWORDs stores the
79 sal_uInt32 mnYResPos; // actual streamposition of the
80 sal_uInt32 mnPalPos; // Tag Entry
81 sal_uInt32 mnBitmapPos;
82 sal_uInt32 mnStripByteCountPos;
83
84 std::unique_ptr<TIFFLZWCTreeNode[]> pTable;
85 TIFFLZWCTreeNode* pPrefix;
86 sal_uInt16 nDataSize;
87 sal_uInt16 nClearCode;
88 sal_uInt16 nEOICode;
89 sal_uInt16 nTableSize;
90 sal_uInt16 nCodeSize;
91 sal_uInt32 nOffset;
92 sal_uInt32 dwShift;
93
94 css::uno::Reference< css::task::XStatusIndicator > xStatusIndicator;
95
96 void ImplCallback( sal_uInt32 nPercent );
97 bool ImplWriteHeader( bool bMultiPage );
98 void ImplWritePalette();
99 void ImplWriteBody();
100 void ImplWriteTag( sal_uInt16 TagID, sal_uInt16 DataType, sal_uInt32 NumberOfItems, sal_uInt32 Value);
101 void ImplWriteResolution( sal_uInt64 nStreamPos, sal_uInt32 nResolutionUnit );
102 void StartCompression();
103 void Compress( sal_uInt8 nSrc );
104 void EndCompression();
105 inline void WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen );
106
107public:
108
109 explicit TIFFWriter(SvStream &rStream);
110
111 bool WriteTIFF( const Graphic& rGraphic, FilterConfigItem const * pFilterConfigItem );
112};
113
114}
115
116TIFFWriter::TIFFWriter(SvStream &rStream)
117 : m_rOStm(rStream)
118 , mnStreamOfs(0)
119 , mbStatus(true)
120 , mpAcc(nullptr)
121 , mnWidth(0)
122 , mnHeight(0)
123 , mnColors(0)
124 , mnCurAllPictHeight(0)
125 , mnSumOfAllPictHeight(0)
126 , mnBitsPerPixel(0)
127 , mnLastPercent(0)
128 , mnLatestIfdPos(0)
129 , mnTagCount(0)
130 , mnCurrentTagCountPos(0)
131 , mnXResPos(0)
132 , mnYResPos(0)
133 , mnPalPos(0)
134 , mnBitmapPos(0)
135 , mnStripByteCountPos(0)
136 , pPrefix(nullptr)
137 , nDataSize(0)
138 , nClearCode(0)
139 , nEOICode(0)
140 , nTableSize(0)
141 , nCodeSize(0)
142 , nOffset(0)
143 , dwShift(0)
144{
145}
146
147
148bool TIFFWriter::WriteTIFF( const Graphic& rGraphic, FilterConfigItem const * pFilterConfigItem)
149{
150 if ( pFilterConfigItem )
151 {
152 xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
153 if ( xStatusIndicator.is() )
154 {
155 xStatusIndicator->start( OUString(), 100 );
156 }
157 }
158
159 const SvStreamEndian nOldFormat = m_rOStm.GetEndian();
160 mnStreamOfs = m_rOStm.Tell();
161
162 // we will use the BIG Endian Mode
163 // TIFF header
164 m_rOStm.SetEndian( SvStreamEndian::BIG );
165 m_rOStm.WriteUInt32( 0x4d4d002a ); // TIFF identifier
166 mnLatestIfdPos = m_rOStm.Tell();
167 m_rOStm.WriteUInt32( 0 );
168
169 if( mbStatus )
170 {
171 Animation aAnimation = rGraphic.IsAnimated() ? rGraphic.GetAnimation() : Animation();
172 if (!rGraphic.IsAnimated())
173 aAnimation.Insert(AnimationFrame(rGraphic.GetBitmapEx(), Point(), Size()));
174
175 for (size_t i = 0; i < aAnimation.Count(); ++i)
176 mnSumOfAllPictHeight += aAnimation.Get(i).maBitmapEx.GetSizePixel().Height();
177
178 for (size_t i = 0; mbStatus && i < aAnimation.Count(); ++i)
179 {
180 mnPalPos = 0;
181 const AnimationFrame& rAnimationFrame = aAnimation.Get( i );
182 Bitmap aBmp = rAnimationFrame.maBitmapEx.GetBitmap();
183 mpAcc = aBmp.AcquireReadAccess();
184 if ( mpAcc )
185 {
186 mnBitsPerPixel = vcl::pixelFormatBitCount(aBmp.getPixelFormat());
187
188 // export code below only handles four discrete cases
189 mnBitsPerPixel =
190 mnBitsPerPixel <= 1 ? 1 : mnBitsPerPixel <= 4 ? 4 : mnBitsPerPixel <= 8 ? 8 : 24;
191
192 if ( ImplWriteHeader( aAnimation.Count() > 0 ) )
193 {
194 Size aDestMapSize( 300, 300 );
195 const MapMode& aMapMode( aBmp.GetPrefMapMode() );
196 if ( aMapMode.GetMapUnit() != MapUnit::MapPixel )
197 {
198 const Size aPrefSize( rGraphic.GetPrefSize() );
199 aDestMapSize = OutputDevice::LogicToLogic(aPrefSize, aMapMode, MapMode(MapUnit::MapInch));
200 }
201 ImplWriteResolution( mnXResPos, aDestMapSize.Width() );
202 ImplWriteResolution( mnYResPos, aDestMapSize.Height() );
203 if ( mnPalPos )
204 ImplWritePalette();
205 ImplWriteBody();
206 }
207 sal_uInt32 nCurPos = m_rOStm.Tell();
208 m_rOStm.Seek( mnCurrentTagCountPos );
209 m_rOStm.WriteUInt16( mnTagCount );
210 m_rOStm.Seek( nCurPos );
211
212 Bitmap::ReleaseAccess( mpAcc );
213 }
214 else
215 mbStatus = false;
216 }
217 }
218 m_rOStm.SetEndian( nOldFormat );
219
220 if ( xStatusIndicator.is() )
221 xStatusIndicator->end();
222
223 return mbStatus;
224}
225
226
227void TIFFWriter::ImplCallback( sal_uInt32 nPercent )
228{
229 if ( xStatusIndicator.is() )
230 {
231 if( nPercent >= mnLastPercent + 3 )
232 {
233 mnLastPercent = nPercent;
234 if ( nPercent <= 100 )
235 xStatusIndicator->setValue( nPercent );
236 }
237 }
238}
239
240
241bool TIFFWriter::ImplWriteHeader( bool bMultiPage )
242{
243 mnTagCount = 0;
244 mnWidth = mpAcc->Width();
245 mnHeight = mpAcc->Height();
246
247 if ( mnWidth && mnHeight && mnBitsPerPixel && mbStatus )
248 {
249 sal_uInt32 nCurrentPos = m_rOStm.Tell();
250 m_rOStm.Seek( mnLatestIfdPos );
251 m_rOStm.WriteUInt32( nCurrentPos - mnStreamOfs ); // offset to the IFD
252 m_rOStm.Seek( nCurrentPos );
253
254 // (OFS8) TIFF image file directory (IFD)
255 mnCurrentTagCountPos = m_rOStm.Tell();
256 m_rOStm.WriteUInt16( 0 ); // the number of tangents to insert later
257
258 sal_uInt32 nSubFileFlags = 0;
259 if ( bMultiPage )
260 nSubFileFlags |= 2;
261 ImplWriteTag( NewSubfileType, 4, 1, nSubFileFlags );
262 ImplWriteTag( ImageWidth, 4, 1, mnWidth );
263 ImplWriteTag( ImageLength, 4, 1, mnHeight);
264 ImplWriteTag( BitsPerSample, 3, 1, ( mnBitsPerPixel == 24 ) ? 8 : mnBitsPerPixel );
265 ImplWriteTag( Compression, 3, 1, 5 );
266 sal_uInt8 nTemp;
267 switch ( mnBitsPerPixel )
268 {
269 case 1 :
270 nTemp = 1;
271 break;
272 case 4 :
273 case 8 :
274 nTemp = 3;
275 break;
276 case 24:
277 nTemp = 2;
278 break;
279 default:
280 nTemp = 0; // -Wall set a default...
281 break;
282 }
283 ImplWriteTag( PhotometricInterpretation, 3, 1, nTemp );
284 mnBitmapPos = m_rOStm.Tell();
285 ImplWriteTag( StripOffsets, 4, 1, 0 );
286 ImplWriteTag( SamplesPerPixel, 3, 1, ( mnBitsPerPixel == 24 ) ? 3 : 1 );
287 ImplWriteTag( RowsPerStrip, 4, 1, mnHeight );
288 mnStripByteCountPos = m_rOStm.Tell();
289 ImplWriteTag( StripByteCounts, 4, 1, ( ( mnWidth * mnBitsPerPixel * mnHeight ) + 7 ) >> 3 );
290 mnXResPos = m_rOStm.Tell();
291 ImplWriteTag( XResolution, 5, 1, 0 );
292 mnYResPos = m_rOStm.Tell();
293 ImplWriteTag( YResolution, 5, 1, 0 );
294 if ( mnBitsPerPixel != 1 )
295 ImplWriteTag( PlanarConfiguration, 3, 1, 1 ); // ( RGB ORDER )
296 ImplWriteTag( ResolutionUnit, 3, 1, 2); // Resolution Unit is Inch
297 if ( ( mnBitsPerPixel == 4 ) || ( mnBitsPerPixel == 8 ) )
298 {
299 mnColors = mpAcc->GetPaletteEntryCount();
300 mnPalPos = m_rOStm.Tell();
301 ImplWriteTag( ColorMap, 3, 3 * mnColors, 0 );
302 }
303
304 // and last we write zero to close the num dir entries list
305 mnLatestIfdPos = m_rOStm.Tell();
306 m_rOStm.WriteUInt32( 0 ); // there are no more IFD
307 }
308 else
309 mbStatus = false;
310
311 return mbStatus;
312}
313
314
315void TIFFWriter::ImplWritePalette()
316{
317 sal_uInt64 nCurrentPos = m_rOStm.Tell();
318 m_rOStm.Seek( mnPalPos + 8 ); // the palette tag entry needs the offset
319 m_rOStm.WriteUInt32( nCurrentPos - mnStreamOfs ); // to the palette colors
320 m_rOStm.Seek( nCurrentPos );
321
322 for ( sal_uInt32 i = 0; i < mnColors; i++ )
323 {
324 const BitmapColor& rColor = mpAcc->GetPaletteColor( i );
325 m_rOStm.WriteUInt16( rColor.GetRed() << 8 );
326 }
327 for ( sal_uInt32 i = 0; i < mnColors; i++ )
328 {
329 const BitmapColor& rColor = mpAcc->GetPaletteColor( i );
330 m_rOStm.WriteUInt16( rColor.GetGreen() << 8 );
331 }
332 for ( sal_uInt32 i = 0; i < mnColors; i++ )
333 {
334 const BitmapColor& rColor = mpAcc->GetPaletteColor( i );
335 m_rOStm.WriteUInt16( rColor.GetBlue() << 8 );
336 }
337}
338
339
340void TIFFWriter::ImplWriteBody()
341{
342 sal_uInt8 nTemp = 0;
343 sal_uInt8 nShift;
344 sal_uInt32 j, x, y;
345
346 sal_uInt64 nGfxBegin = m_rOStm.Tell();
347 m_rOStm.Seek( mnBitmapPos + 8 ); // the strip offset tag entry needs the offset
348 m_rOStm.WriteUInt32( nGfxBegin - mnStreamOfs ); // to the bitmap data
349 m_rOStm.Seek( nGfxBegin );
350
351 StartCompression();
352
353 switch( mnBitsPerPixel )
354 {
355 case 24 :
356 {
357 for ( y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
358 {
359 ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
360 Scanline pScanline = mpAcc->GetScanline( y );
361 for ( x = 0; x < mnWidth; x++ )
362 {
363 const BitmapColor& rColor = mpAcc->GetPixelFromData( pScanline, x );
364 Compress( rColor.GetRed() );
365 Compress( rColor.GetGreen() );
366 Compress( rColor.GetBlue() );
367 }
368 }
369 }
370 break;
371
372 case 8 :
373 {
374 for ( y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
375 {
376 ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
377 Scanline pScanline = mpAcc->GetScanline( y );
378 for ( x = 0; x < mnWidth; x++ )
379 {
380 Compress( mpAcc->GetIndexFromData( pScanline, x ) );
381 }
382 }
383 }
384 break;
385
386 case 4 :
387 {
388 for ( nShift = 0, y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
389 {
390 ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
391 Scanline pScanline = mpAcc->GetScanline( y );
392 for ( x = 0; x < mnWidth; x++, nShift++ )
393 {
394 if (!( nShift & 1 ))
395 nTemp = ( mpAcc->GetIndexFromData( pScanline, x ) << 4 );
396 else
397 Compress( static_cast<sal_uInt8>( nTemp | ( mpAcc->GetIndexFromData( pScanline, x ) & 0xf ) ) );
398 }
399 if ( nShift & 1 )
400 Compress( nTemp );
401 }
402 }
403 break;
404
405 case 1 :
406 {
407 j = 1;
408 for ( y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
409 {
410 ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
411 Scanline pScanline = mpAcc->GetScanline( y );
412 for ( x = 0; x < mnWidth; x++)
413 {
414 j <<= 1;
415 j |= ( ( ~mpAcc->GetIndexFromData( pScanline, x ) ) & 1 );
416 if ( j & 0x100 )
417 {
418 Compress( static_cast<sal_uInt8>(j) );
419 j = 1;
420 }
421 }
422 if ( j != 1 )
423 {
424 Compress( static_cast<sal_uInt8>(j << ( ( ( x & 7) ^ 7 ) + 1 ) ) );
425 j = 1;
426 }
427 }
428 }
429 break;
430
431 default:
432 {
433 mbStatus = false;
434 }
435 break;
436 }
437
438 EndCompression();
439
440 if ( mnStripByteCountPos && mbStatus )
441 {
442 sal_uInt64 nGfxEnd = m_rOStm.Tell();
443 m_rOStm.Seek( mnStripByteCountPos + 8 );
444 m_rOStm.WriteUInt32( nGfxEnd - nGfxBegin ); // mnStripByteCountPos needs the size of the compression data
445 m_rOStm.Seek( nGfxEnd );
446 }
447}
448
449
450void TIFFWriter::ImplWriteResolution( sal_uInt64 nStreamPos, sal_uInt32 nResolutionUnit )
451{
452 sal_uInt64 nCurrentPos = m_rOStm.Tell();
453 m_rOStm.Seek( nStreamPos + 8 );
454 m_rOStm.WriteUInt32( nCurrentPos - mnStreamOfs );
455 m_rOStm.Seek( nCurrentPos );
456 m_rOStm.WriteUInt32( 1 );
457 m_rOStm.WriteUInt32( nResolutionUnit );
458}
459
460
461void TIFFWriter::ImplWriteTag( sal_uInt16 nTagID, sal_uInt16 nDataType, sal_uInt32 nNumberOfItems, sal_uInt32 nValue)
462{
463 mnTagCount++;
464
465 m_rOStm.WriteUInt16( nTagID );
466 m_rOStm.WriteUInt16( nDataType );
467 m_rOStm.WriteUInt32( nNumberOfItems );
468 if ( nDataType == 3 )
469 nValue <<=16; // in Big Endian Mode WORDS needed to be shifted to a DWORD
470 m_rOStm.WriteUInt32( nValue );
471}
472
473
474inline void TIFFWriter::WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen )
475{
476 dwShift |= ( nCode << ( nOffset - nCodeLen ) );
477 nOffset -= nCodeLen;
478 while ( nOffset < 24 )
479 {
480 m_rOStm.WriteUChar( dwShift >> 24 );
481 dwShift <<= 8;
482 nOffset += 8;
483 }
484 if ( nCode == 257 && nOffset != 32 )
485 {
486 m_rOStm.WriteUChar( dwShift >> 24 );
487 }
488}
489
490
491void TIFFWriter::StartCompression()
492{
493 sal_uInt16 i;
494 nDataSize = 8;
495
496 nClearCode = 1 << nDataSize;
497 nEOICode = nClearCode + 1;
498 nTableSize = nEOICode + 1;
499 nCodeSize = nDataSize + 1;
500
501 nOffset = 32; // number of free bits in dwShift
502 dwShift = 0;
503
504 pTable.reset(new TIFFLZWCTreeNode[ 4096 ]);
505
506 for ( i = 0; i < 4096; i++)
507 {
508 pTable[ i ].pBrother = pTable[ i ].pFirstChild = nullptr;
509 pTable[ i ].nCode = i;
510 pTable[ i ].nValue = static_cast<sal_uInt8>( i );
511 }
512
513 pPrefix = nullptr;
514 WriteBits( nClearCode, nCodeSize );
515}
516
517
518void TIFFWriter::Compress( sal_uInt8 nCompThis )
519{
520 TIFFLZWCTreeNode* p;
521 sal_uInt16 i;
522 sal_uInt8 nV;
523
524 if( !pPrefix )
525 {
526 pPrefix = &pTable[nCompThis];
527 }
528 else
529 {
530 nV = nCompThis;
531 for( p = pPrefix->pFirstChild; p != nullptr; p = p->pBrother )
532 {
533 if ( p->nValue == nV )
534 break;
535 }
536
537 if( p )
538 pPrefix = p;
539 else
540 {
541 WriteBits( pPrefix->nCode, nCodeSize );
542
543 if ( nTableSize == 409 )
544 {
545 WriteBits( nClearCode, nCodeSize );
546
547 for ( i = 0; i < nClearCode; i++ )
548 pTable[ i ].pFirstChild = nullptr;
549
550 nCodeSize = nDataSize + 1;
551 nTableSize = nEOICode + 1;
552 }
553 else
554 {
555 if( nTableSize == static_cast<sal_uInt16>( ( 1 << nCodeSize ) - 1 ) )
556 nCodeSize++;
557
558 p = &pTable[ nTableSize++ ];
559 p->pBrother = pPrefix->pFirstChild;
560 pPrefix->pFirstChild = p;
561 p->nValue = nV;
562 p->pFirstChild = nullptr;
563 }
564
565 pPrefix = &pTable[nV];
566 }
567 }
568}
569
570
571void TIFFWriter::EndCompression()
572{
573 if( pPrefix )
574 WriteBits( pPrefix->nCode, nCodeSize );
575
576 WriteBits( nEOICode, nCodeSize );
577 pTable.reset();
578}
579
580bool ExportTiffGraphicImport(SvStream & rStream, const Graphic & rGraphic, const FilterConfigItem* pFilterConfigItem)
581{
582 TIFFWriter aWriter(rStream);
583 return aWriter.WriteTIFF( rGraphic, pFilterConfigItem );
584}
585
586/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
size_t Count() const
Definition: Animation.hxx:71
const AnimationFrame & Get(sal_uInt16 nAnimation) const
Definition: Animation.cxx:434
bool Insert(const AnimationFrame &rAnimationFrame)
Definition: Animation.cxx:411
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:217
const Size & GetSizePixel() const
Definition: bitmapex.hxx:73
const MapMode & GetPrefMapMode() const
static void ReleaseAccess(BitmapInfoAccess *pAccess)
BitmapReadAccess * AcquireReadAccess()
vcl::PixelFormat getPixelFormat() const
sal_uInt8 GetBlue() const
sal_uInt8 GetRed() const
sal_uInt8 GetGreen() const
css::uno::Reference< css::task::XStatusIndicator > GetStatusIndicator() const
Size GetPrefSize() const
Definition: graph.cxx:364
Animation GetAnimation() const
Definition: graph.cxx:335
bool IsAnimated() const
Definition: graph.cxx:320
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
Definition: graph.cxx:330
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1580
constexpr tools::Long Height() const
float y
float x
#define NewSubfileType
Definition: etiff.cxx:29
#define ImageWidth
Definition: etiff.cxx:30
#define SamplesPerPixel
Definition: etiff.cxx:36
#define Compression
Definition: etiff.cxx:33
#define YResolution
Definition: etiff.cxx:40
#define ColorMap
Definition: etiff.cxx:43
#define XResolution
Definition: etiff.cxx:39
#define PlanarConfiguration
Definition: etiff.cxx:41
#define StripByteCounts
Definition: etiff.cxx:38
bool ExportTiffGraphicImport(SvStream &rStream, const Graphic &rGraphic, const FilterConfigItem *pFilterConfigItem)
Definition: etiff.cxx:580
#define ResolutionUnit
Definition: etiff.cxx:42
#define StripOffsets
Definition: etiff.cxx:35
#define BitsPerSample
Definition: etiff.cxx:32
#define ImageLength
Definition: etiff.cxx:31
#define RowsPerStrip
Definition: etiff.cxx:37
#define PhotometricInterpretation
Definition: etiff.cxx:34
sal_Int16 nValue
void * p
Value
int i
DataType
constexpr sal_uInt16 pixelFormatBitCount(PixelFormat ePixelFormat)
Definition: BitmapTypes.hxx:34
double mnWidth
double mnHeight
SvStreamEndian
unsigned char sal_uInt8