LibreOffice Module vcl (master)  1
GraphicFormatDetector.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 #include <sal/config.h>
21 
22 #include <algorithm>
23 
26 #include <tools/solar.h>
27 #include <tools/zcodec.hxx>
28 
29 namespace vcl
30 {
31 bool peekGraphicFormat(SvStream& rStream, OUString& rFormatExtension, bool bTest)
32 {
33  vcl::GraphicFormatDetector aDetector(rStream, rFormatExtension);
34  if (!aDetector.detect())
35  return false;
36 
37  // The following variable is used when bTest == true. It remains false
38  // if the format (rFormatExtension) has not yet been set.
39  bool bSomethingTested = false;
40 
41  // Now the different formats are checked. The order *does* matter. e.g. a MET file
42  // could also go through the BMP test, however, a BMP file can hardly go through the MET test.
43  // So MET should be tested prior to BMP. However, theoretically a BMP file could conceivably
44  // go through the MET test. These problems are of course not only in MET and BMP.
45  // Therefore, in the case of a format check (bTest == true) we only test *exactly* this
46  // format. Everything else could have fatal consequences, for example if the user says it is
47  // a BMP file (and it is a BMP) file, and the file would go through the MET test ...
48 
49  if (!bTest || rFormatExtension.startsWith("MET"))
50  {
51  bSomethingTested = true;
52  if (aDetector.checkMET())
53  {
54  rFormatExtension = aDetector.msDetectedFormat;
55  return true;
56  }
57  }
58 
59  if (!bTest || rFormatExtension.startsWith("BMP"))
60  {
61  bSomethingTested = true;
62  if (aDetector.checkBMP())
63  {
64  rFormatExtension = aDetector.msDetectedFormat;
65  return true;
66  }
67  }
68 
69  if (!bTest || rFormatExtension.startsWith("WMF") || rFormatExtension.startsWith("EMF"))
70  {
71  bSomethingTested = true;
72  if (aDetector.checkWMForEMF())
73  {
74  rFormatExtension = aDetector.msDetectedFormat;
75  return true;
76  }
77  }
78 
79  if (!bTest || rFormatExtension.startsWith("PCX"))
80  {
81  bSomethingTested = true;
82  if (aDetector.checkPCX())
83  {
84  rFormatExtension = aDetector.msDetectedFormat;
85  return true;
86  }
87  }
88 
89  if (!bTest || rFormatExtension.startsWith("TIF"))
90  {
91  bSomethingTested = true;
92  if (aDetector.checkTIF())
93  {
94  rFormatExtension = aDetector.msDetectedFormat;
95  return true;
96  }
97  }
98 
99  if (!bTest || rFormatExtension.startsWith("GIF"))
100  {
101  bSomethingTested = true;
102  if (aDetector.checkGIF())
103  {
104  rFormatExtension = aDetector.msDetectedFormat;
105  return true;
106  }
107  }
108 
109  if (!bTest || rFormatExtension.startsWith("PNG"))
110  {
111  bSomethingTested = true;
112  if (aDetector.checkPNG())
113  {
114  rFormatExtension = aDetector.msDetectedFormat;
115  return true;
116  }
117  }
118 
119  if (!bTest || rFormatExtension.startsWith("JPG"))
120  {
121  bSomethingTested = true;
122  if (aDetector.checkJPG())
123  {
124  rFormatExtension = aDetector.msDetectedFormat;
125  return true;
126  }
127  }
128 
129  if (!bTest || rFormatExtension.startsWith("SVM"))
130  {
131  bSomethingTested = true;
132  if (aDetector.checkSVM())
133  {
134  rFormatExtension = aDetector.msDetectedFormat;
135  return true;
136  }
137  }
138 
139  if (!bTest || rFormatExtension.startsWith("PCD"))
140  {
141  bSomethingTested = true;
142  if (aDetector.checkPCD())
143  {
144  rFormatExtension = aDetector.msDetectedFormat;
145  return true;
146  }
147  }
148 
149  if (!bTest || rFormatExtension.startsWith("PSD"))
150  {
151  bSomethingTested = true;
152  if (aDetector.checkPSD())
153  {
154  rFormatExtension = aDetector.msDetectedFormat;
155  return true;
156  }
157  }
158 
159  if (!bTest || rFormatExtension.startsWith("EPS"))
160  {
161  bSomethingTested = true;
162  if (aDetector.checkEPS())
163  {
164  rFormatExtension = aDetector.msDetectedFormat;
165  return true;
166  }
167  }
168 
169  if (!bTest || rFormatExtension.startsWith("DXF"))
170  {
171  if (aDetector.checkDXF())
172  {
173  rFormatExtension = aDetector.msDetectedFormat;
174  return true;
175  }
176  }
177 
178  if (!bTest || rFormatExtension.startsWith("PCT"))
179  {
180  bSomethingTested = true;
181  if (aDetector.checkPCT())
182  {
183  rFormatExtension = aDetector.msDetectedFormat;
184  return true;
185  }
186  }
187 
188  if (!bTest || rFormatExtension.startsWith("PBM") || rFormatExtension.startsWith("PGM")
189  || rFormatExtension.startsWith("PPM"))
190  {
191  bSomethingTested = true;
192  if (aDetector.checkPBMorPGMorPPM())
193  {
194  rFormatExtension = aDetector.msDetectedFormat;
195  return true;
196  }
197  }
198 
199  if (!bTest || rFormatExtension.startsWith("RAS"))
200  {
201  bSomethingTested = true;
202  if (aDetector.checkRAS())
203  {
204  rFormatExtension = aDetector.msDetectedFormat;
205  return true;
206  }
207  }
208 
209  if (!bTest)
210  {
211  bSomethingTested = true;
212  if (aDetector.checkXPM())
213  {
214  rFormatExtension = aDetector.msDetectedFormat;
215  return true;
216  }
217  }
218  else if (rFormatExtension.startsWith("XPM"))
219  {
220  return true;
221  }
222 
223  if (!bTest)
224  {
225  if (aDetector.checkXBM())
226  {
227  rFormatExtension = aDetector.msDetectedFormat;
228  return true;
229  }
230  }
231  else if (rFormatExtension.startsWith("XBM"))
232  {
233  return true;
234  }
235 
236  if (!bTest)
237  {
238  if (aDetector.checkSVG())
239  {
240  rFormatExtension = aDetector.msDetectedFormat;
241  return true;
242  }
243  }
244  else if (rFormatExtension.startsWith("SVG"))
245  {
246  return true;
247  }
248 
249  if (!bTest || rFormatExtension.startsWith("TGA"))
250  {
251  bSomethingTested = true;
252  if (aDetector.checkTGA())
253  {
254  rFormatExtension = aDetector.msDetectedFormat;
255  return true;
256  }
257  }
258 
259  if (!bTest || rFormatExtension.startsWith("MOV"))
260  {
261  if (aDetector.checkMOV())
262  {
263  rFormatExtension = aDetector.msDetectedFormat;
264  return true;
265  }
266  }
267 
268  if (!bTest || rFormatExtension.startsWith("PDF"))
269  {
270  if (aDetector.checkPDF())
271  {
272  rFormatExtension = aDetector.msDetectedFormat;
273  return true;
274  }
275  }
276 
277  return bTest && !bSomethingTested;
278 }
279 
280 namespace
281 {
282 bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
283 {
284  sal_uInt8 sBuf[3];
285  // store number format
286  SvStreamEndian oldNumberFormat = rStream.GetEndian();
287  sal_uInt32 nOffset; // in MS documents the pict format is used without the first 512 bytes
288  for (nOffset = 0; (nOffset <= 512) && ((nStreamPos + nOffset + 14) <= nStreamLen);
289  nOffset += 512)
290  {
291  short y1, x1, y2, x2;
292  bool bdBoxOk = true;
293 
294  rStream.Seek(nStreamPos + nOffset);
295  // size of the pict in version 1 pict ( 2bytes) : ignored
296  rStream.SeekRel(2);
297  // bounding box (bytes 2 -> 9)
298  rStream.SetEndian(SvStreamEndian::BIG);
299  rStream.ReadInt16(y1).ReadInt16(x1).ReadInt16(y2).ReadInt16(x2);
300  rStream.SetEndian(oldNumberFormat); // reset format
301 
302  if (x1 > x2 || y1 > y2 || // bad bdbox
303  (x1 == x2 && y1 == y2) || // 1 pixel picture
304  x2 - x1 > 2048 || y2 - y1 > 2048) // picture abnormally big
305  bdBoxOk = false;
306 
307  // read version op
308  rStream.ReadBytes(sBuf, 3);
309  // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
310  // normal version 2 - page A23 and A24
311  if (sBuf[0] == 0x00 && sBuf[1] == 0x11 && sBuf[2] == 0x02)
312  return true;
313  // normal version 1 - page A25
314  else if (sBuf[0] == 0x11 && sBuf[1] == 0x01 && bdBoxOk)
315  return true;
316  }
317  return false;
318 }
319 
320 } // end anonymous namespace
321 
322 GraphicFormatDetector::GraphicFormatDetector(SvStream& rStream, OUString const& rFormatExtension)
323  : mrStream(rStream)
324  , maExtension(rFormatExtension)
325  , mnFirstLong(0)
326  , mnSecondLong(0)
327  , mnStreamPosition(0)
328  , mnStreamLength(0)
329 {
330 }
331 
333 {
334  maFirstBytes.clear();
335  maFirstBytes.resize(256, 0);
336 
337  mnFirstLong = 0;
338  mnSecondLong = 0;
339 
342 
343  if (!mnStreamLength)
344  {
345  SvLockBytes* pLockBytes = mrStream.GetLockBytes();
346  if (pLockBytes)
347  pLockBytes->SetSynchronMode();
349  }
350 
351  if (mnStreamLength == 0)
352  {
353  return false; // this prevents at least a STL assertion
354  }
355  else if (mnStreamLength >= maFirstBytes.size())
356  {
357  // load first 256 bytes into a buffer
358  sal_uInt64 nRead = mrStream.ReadBytes(maFirstBytes.data(), maFirstBytes.size());
359  if (nRead < maFirstBytes.size())
360  mnStreamLength = nRead;
361  }
362  else
363  {
365  }
366 
367  if (mrStream.GetError())
368  return false;
369 
370  for (int i = 0; i < 4; ++i)
371  {
372  mnFirstLong = (mnFirstLong << 8) | sal_uInt32(maFirstBytes[i]);
373  mnSecondLong = (mnSecondLong << 8) | sal_uInt32(maFirstBytes[i + 4]);
374  }
375  return true;
376 }
377 
379 {
380  if (maFirstBytes[2] != 0xd3)
381  return false;
382  mrStream.SetEndian(SvStreamEndian::BIG);
384  sal_uInt16 nFieldSize;
386 
387  mrStream.ReadUInt16(nFieldSize).ReadUChar(nMagic);
388  for (int i = 0; i < 3; i++)
389  {
390  if (nFieldSize < 6)
391  return false;
392  if (mnStreamLength < mrStream.Tell() + nFieldSize)
393  return false;
394  mrStream.SeekRel(nFieldSize - 3);
395  mrStream.ReadUInt16(nFieldSize).ReadUChar(nMagic);
396  if (nMagic != 0xd3)
397  return false;
398  }
399  mrStream.SetEndian(SvStreamEndian::LITTLE);
400 
401  if (mrStream.GetError())
402  return false;
403 
404  msDetectedFormat = "MET";
405  return true;
406 }
407 
409 {
410  sal_uInt8 nOffset;
411 
412  // We're possibly also able to read an OS/2 bitmap array
413  // ('BA'), therefore we must adjust the offset to discover the
414  // first bitmap in the array
415  if (maFirstBytes[0] == 0x42 && maFirstBytes[1] == 0x41)
416  nOffset = 14;
417  else
418  nOffset = 0;
419 
420  // Now we initially test on 'BM'
421  if (maFirstBytes[0 + nOffset] == 0x42 && maFirstBytes[1 + nOffset] == 0x4d)
422  {
423  // OS/2 can set the Reserved flags to a value other than 0
424  // (which they really should not do...);
425  // In this case we test the size of the BmpInfoHeaders
426  if ((maFirstBytes[6 + nOffset] == 0x00 && maFirstBytes[7 + nOffset] == 0x00
427  && maFirstBytes[8 + nOffset] == 0x00 && maFirstBytes[9 + nOffset] == 0x00)
428  || maFirstBytes[14 + nOffset] == 0x28 || maFirstBytes[14 + nOffset] == 0x0c)
429  {
430  msDetectedFormat = "BMP";
431  return true;
432  }
433  }
434  return false;
435 }
436 
438 {
439  if (mnFirstLong == 0xd7cdc69a || mnFirstLong == 0x01000900)
440  {
441  msDetectedFormat = "WMF";
442  return true;
443  }
444  else if (mnFirstLong == 0x01000000 && maFirstBytes[40] == 0x20 && maFirstBytes[41] == 0x45
445  && maFirstBytes[42] == 0x4d && maFirstBytes[43] == 0x46)
446  {
447  msDetectedFormat = "EMF";
448  return true;
449  }
450  return false;
451 }
452 
454 {
455  if (maFirstBytes[0] != 0x0a)
456  return false;
457 
459  sal_uInt8 nEncoding = maFirstBytes[2];
460  if ((nVersion == 0 || nVersion == 2 || nVersion == 3 || nVersion == 5) && nEncoding <= 1)
461  {
462  msDetectedFormat = "PCX";
463  return true;
464  }
465 
466  return false;
467 }
468 
470 {
471  if (mnFirstLong == 0x49492a00 || mnFirstLong == 0x4d4d002a)
472  {
473  msDetectedFormat = "TIF";
474  return true;
475  }
476  return false;
477 }
478 
480 {
481  if (mnFirstLong == 0x47494638 && (maFirstBytes[4] == 0x37 || maFirstBytes[4] == 0x39)
482  && maFirstBytes[5] == 0x61)
483  {
484  msDetectedFormat = "GIF";
485  return true;
486  }
487  return false;
488 }
489 
491 {
492  if (mnFirstLong == 0x89504e47 && mnSecondLong == 0x0d0a1a0a)
493  {
494  msDetectedFormat = "PNG";
495  return true;
496  }
497  return false;
498 }
499 
501 {
502  if ((mnFirstLong == 0xffd8ffe0 && maFirstBytes[6] == 0x4a && maFirstBytes[7] == 0x46
503  && maFirstBytes[8] == 0x49 && maFirstBytes[9] == 0x46)
504  || (mnFirstLong == 0xffd8fffe) || (0xffd8ff00 == (mnFirstLong & 0xffffff00)))
505  {
506  msDetectedFormat = "JPG";
507  return true;
508  }
509  return false;
510 }
511 
513 {
514  if (mnFirstLong == 0x53564744 && maFirstBytes[4] == 0x49)
515  {
516  msDetectedFormat = "SVM";
517  return true;
518  }
519  else if (maFirstBytes[0] == 0x56 && maFirstBytes[1] == 0x43 && maFirstBytes[2] == 0x4C
520  && maFirstBytes[3] == 0x4D && maFirstBytes[4] == 0x54 && maFirstBytes[5] == 0x46)
521  {
522  msDetectedFormat = "SVM";
523  return true;
524  }
525  return false;
526 }
527 
529 {
530  if (mnStreamLength < 2055)
531  return false;
532  char sBuffer[8];
534  mrStream.ReadBytes(sBuffer, 7);
535 
536  if (strncmp(sBuffer, "PCD_IPI", 7) == 0)
537  {
538  msDetectedFormat = "PCD";
539  return true;
540  }
541  return false;
542 }
543 
545 {
546  if ((mnFirstLong == 0x38425053) && ((mnSecondLong >> 16) == 1))
547  {
548  msDetectedFormat = "PSD";
549  return true;
550  }
551  return false;
552 }
553 
555 {
556  const char* pFirstBytesAsCharArray = reinterpret_cast<char*>(maFirstBytes.data());
557 
558  if (mnFirstLong == 0xC5D0D3C6)
559  {
560  msDetectedFormat = "EPS";
561  return true;
562  }
563  else if (checkArrayForMatchingStrings(pFirstBytesAsCharArray, 30, { "%!PS-Adobe", " EPS" }))
564  {
565  msDetectedFormat = "EPS";
566  return true;
567  }
568 
569  return false;
570 }
571 
573 {
574  if (strncmp(reinterpret_cast<char*>(maFirstBytes.data()), "AutoCAD Binary DXF", 18) == 0)
575  {
576  msDetectedFormat = "DXF";
577  return true;
578  }
579 
580  // ASCII DXF File Format
581  int i = 0;
582  while (i < 256 && maFirstBytes[i] <= 32)
583  {
584  ++i;
585  }
586 
587  if (i < 256 && maFirstBytes[i] == '0')
588  {
589  ++i;
590 
591  // only now do we have sufficient data to make a judgement
592  // based on a '0' + 'SECTION' == DXF argument
593 
594  while (i < 256 && maFirstBytes[i] <= 32)
595  {
596  ++i;
597  }
598 
599  if (i + 7 < 256
600  && (strncmp(reinterpret_cast<char*>(maFirstBytes.data() + i), "SECTION", 7) == 0))
601  {
602  msDetectedFormat = "DXF";
603  return true;
604  }
605  }
606  return false;
607 }
608 
610 {
612  {
613  msDetectedFormat = "PCT";
614  return true;
615  }
616  return false;
617 }
618 
620 {
621  if (maFirstBytes[0] == 'P')
622  {
623  switch (maFirstBytes[1])
624  {
625  case '1':
626  case '4':
627  msDetectedFormat = "PBM";
628  return true;
629 
630  case '2':
631  case '5':
632  msDetectedFormat = "PGM";
633  return true;
634 
635  case '3':
636  case '6':
637  msDetectedFormat = "PPM";
638  return true;
639  }
640  }
641  return false;
642 }
643 
645 {
646  if (mnFirstLong == 0x59a66a95)
647  {
648  msDetectedFormat = "RAS";
649  return true;
650  }
651  return false;
652 }
653 
655 {
656  const char* pFirstBytesAsCharArray = reinterpret_cast<char*>(maFirstBytes.data());
657  if (matchArrayWithString(pFirstBytesAsCharArray, 256, "/* XPM */"))
658  {
659  msDetectedFormat = "XPM";
660  return true;
661  }
662  return false;
663 }
664 
666 {
667  sal_uInt64 nSize = std::min<sal_uInt64>(mnStreamLength, 2048);
668  std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nSize]);
669 
671  mrStream.ReadBytes(pBuffer.get(), nSize);
672 
673  const char* pBufferAsCharArray = reinterpret_cast<char*>(pBuffer.get());
674 
675  if (checkArrayForMatchingStrings(pBufferAsCharArray, nSize, { "#define", "_width" }))
676  {
677  msDetectedFormat = "XBM";
678  return true;
679  }
680  return false;
681 }
682 
684 {
685  sal_uInt8* pCheckArray = maFirstBytes.data();
686  sal_uInt64 nCheckSize = std::min<sal_uInt64>(mnStreamLength, 256);
687 
688  sal_uInt8 sExtendedOrDecompressedFirstBytes[2048];
689  sal_uInt64 nDecompressedSize = nCheckSize;
690 
691  bool bIsGZip(false);
692 
693  // check if it is gzipped -> svgz
694  if (maFirstBytes[0] == 0x1F && maFirstBytes[1] == 0x8B)
695  {
696  ZCodec aCodec;
698  aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/ true);
699  nDecompressedSize = aCodec.Read(mrStream, sExtendedOrDecompressedFirstBytes, 2048);
700  nCheckSize = std::min<sal_uInt64>(nDecompressedSize, 256);
701  aCodec.EndCompression();
702  pCheckArray = sExtendedOrDecompressedFirstBytes;
703 
704  bIsGZip = true;
705  }
706 
707  bool bIsSvg(false);
708 
709  const char* pCheckArrayAsCharArray = reinterpret_cast<char*>(pCheckArray);
710 
711  // check for XML
712  // #119176# SVG files which have no xml header at all have shown up this is optional
713  // check for "xml" then "version" then "DOCTYPE" and "svg" tags
714  if (checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize,
715  { "<?xml", "version", "DOCTYPE", "svg" }))
716  {
717  bIsSvg = true;
718  }
719 
720  // check for svg element in 1st 256 bytes
721  // search for '<svg'
722  if (!bIsSvg && checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize, { "<svg" }))
723  {
724  bIsSvg = true;
725  }
726 
727  // extended search for svg element
728  if (!bIsSvg)
729  {
730  // it's a xml, look for '<svg' in full file. Should not happen too
731  // often since the tests above will handle most cases, but can happen
732  // with Svg files containing big comment headers or Svg as the host
733  // language
734 
735  pCheckArrayAsCharArray = reinterpret_cast<char*>(sExtendedOrDecompressedFirstBytes);
736 
737  if (bIsGZip)
738  {
739  nCheckSize = std::min<sal_uInt64>(nDecompressedSize, 2048);
740  }
741  else
742  {
743  nCheckSize = std::min<sal_uInt64>(mnStreamLength, 2048);
745  nCheckSize = mrStream.ReadBytes(sExtendedOrDecompressedFirstBytes, nCheckSize);
746  }
747 
748  // search for '<svg'
749  if (checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize, { "<svg" }))
750  {
751  bIsSvg = true;
752  }
753  }
754 
755  if (bIsSvg)
756  {
757  msDetectedFormat = "SVG";
758  return true;
759  }
760  return false;
761 }
762 
764 {
765  // Check TGA ver.2 footer bytes
766  if (mnStreamLength > 18)
767  {
768  char sFooterBytes[18];
769 
771  mrStream.SeekRel(-18);
772  mrStream.ReadBytes(sFooterBytes, 18);
773 
774  if (memcmp(sFooterBytes, "TRUEVISION-XFILE.", SAL_N_ELEMENTS(sFooterBytes)) == 0)
775  {
776  msDetectedFormat = "TGA";
777  return true;
778  }
779  }
780 
781  // Fallback to file extension check
782  if (maExtension.startsWith("TGA"))
783  {
784  msDetectedFormat = "TGA";
785  return true;
786  }
787  return false;
788 }
789 
791 {
792  if ((maFirstBytes[4] == 'f' && maFirstBytes[5] == 't' && maFirstBytes[6] == 'y'
793  && maFirstBytes[7] == 'p' && maFirstBytes[8] == 'q' && maFirstBytes[9] == 't')
794  || (maFirstBytes[4] == 'm' && maFirstBytes[5] == 'o' && maFirstBytes[6] == 'o'
795  && maFirstBytes[7] == 'v' && maFirstBytes[11] == 'l' && maFirstBytes[12] == 'm'))
796  {
797  msDetectedFormat = "MOV";
798  return true;
799  }
800  return false;
801 }
802 
804 {
805  if (maFirstBytes[0] == '%' && maFirstBytes[1] == 'P' && maFirstBytes[2] == 'D'
806  && maFirstBytes[3] == 'F' && maFirstBytes[4] == '-')
807  {
808  msDetectedFormat = "PDF";
809  return true;
810  }
811  return false;
812 }
813 
814 } // vcl namespace
815 
816 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvStream & ReadInt16(sal_Int16 &rInt16)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
void SetSynchronMode(bool bTheSync=true)
sal_uIntPtr sal_uLong
#define ZCODEC_DEFAULT_COMPRESSION
bool isPCT(SvStream &rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
#define STREAM_SEEK_TO_END
const char * matchArrayWithString(const char *pSource, sal_Int32 nSourceSize, OString const &rString)
sal_uInt64 Seek(sal_uInt64 nPos)
sal_uInt64 SeekRel(sal_Int64 nPos)
ErrCode GetError() const
SvLockBytes * GetLockBytes() const
const sal_uInt16 nMagic
GraphicFormatDetector(SvStream &rStream, OUString const &rFormatExtension)
sal_uInt64 remainingSize()
#define SAL_N_ELEMENTS(arr)
int i
bool checkArrayForMatchingStrings(const char *pSource, sal_Int32 nSourceSize, std::vector< OString > const &rStrings)
void BeginCompression(int nCompressLevel=ZCODEC_DEFAULT_COMPRESSION, bool gzLib=false)
tools::Long EndCompression()
SvStream & ReadUChar(unsigned char &rChar)
sal_Int16 nVersion
tools::Long Read(SvStream &rIStm, sal_uInt8 *pData, sal_uInt32 nSize)
std::vector< sal_uInt8 > maFirstBytes
std::size_t ReadBytes(void *pData, std::size_t nSize)
SvStreamEndian GetEndian() const
unsigned char sal_uInt8
void SetEndian(SvStreamEndian SvStreamEndian)
sal_uInt64 Tell() const
bool peekGraphicFormat(SvStream &rStream, OUString &rFormatExtension, bool bTest)
SvStreamEndian