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  // read version op
303  rStream.ReadBytes(sBuf, 3);
304 
305  if (!rStream.good())
306  break;
307 
308  if (x1 > x2 || y1 > y2 || // bad bdbox
309  (x1 == x2 && y1 == y2) || // 1 pixel picture
310  x2 - x1 > 2048 || y2 - y1 > 2048) // picture abnormally big
311  bdBoxOk = false;
312 
313  // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
314  // normal version 2 - page A23 and A24
315  if (sBuf[0] == 0x00 && sBuf[1] == 0x11 && sBuf[2] == 0x02)
316  return true;
317  // normal version 1 - page A25
318  else if (sBuf[0] == 0x11 && sBuf[1] == 0x01 && bdBoxOk)
319  return true;
320  }
321  return false;
322 }
323 
324 } // end anonymous namespace
325 
326 GraphicFormatDetector::GraphicFormatDetector(SvStream& rStream, OUString const& rFormatExtension)
327  : mrStream(rStream)
328  , maExtension(rFormatExtension)
329  , mnFirstLong(0)
330  , mnSecondLong(0)
331  , mnStreamPosition(0)
332  , mnStreamLength(0)
333 {
334 }
335 
337 {
338  maFirstBytes.clear();
339  maFirstBytes.resize(256, 0);
340 
341  mnFirstLong = 0;
342  mnSecondLong = 0;
343 
346 
347  if (!mnStreamLength)
348  {
349  SvLockBytes* pLockBytes = mrStream.GetLockBytes();
350  if (pLockBytes)
351  pLockBytes->SetSynchronMode();
353  }
354 
355  if (mnStreamLength == 0)
356  {
357  return false; // this prevents at least a STL assertion
358  }
359  else if (mnStreamLength >= maFirstBytes.size())
360  {
361  // load first 256 bytes into a buffer
362  sal_uInt64 nRead = mrStream.ReadBytes(maFirstBytes.data(), maFirstBytes.size());
363  if (nRead < maFirstBytes.size())
364  mnStreamLength = nRead;
365  }
366  else
367  {
369  }
370 
371  if (mrStream.GetError())
372  return false;
373 
374  for (int i = 0; i < 4; ++i)
375  {
376  mnFirstLong = (mnFirstLong << 8) | sal_uInt32(maFirstBytes[i]);
377  mnSecondLong = (mnSecondLong << 8) | sal_uInt32(maFirstBytes[i + 4]);
378  }
379  return true;
380 }
381 
383 {
384  if (maFirstBytes[2] != 0xd3)
385  return false;
386  mrStream.SetEndian(SvStreamEndian::BIG);
388  sal_uInt16 nFieldSize;
390 
391  mrStream.ReadUInt16(nFieldSize).ReadUChar(nMagic);
392  for (int i = 0; i < 3; i++)
393  {
394  if (nFieldSize < 6)
395  return false;
396  if (mnStreamLength < mrStream.Tell() + nFieldSize)
397  return false;
398  mrStream.SeekRel(nFieldSize - 3);
399  mrStream.ReadUInt16(nFieldSize).ReadUChar(nMagic);
400  if (nMagic != 0xd3)
401  return false;
402  }
403  mrStream.SetEndian(SvStreamEndian::LITTLE);
404 
405  if (mrStream.GetError())
406  return false;
407 
408  msDetectedFormat = "MET";
409  return true;
410 }
411 
413 {
414  sal_uInt8 nOffset;
415 
416  // We're possibly also able to read an OS/2 bitmap array
417  // ('BA'), therefore we must adjust the offset to discover the
418  // first bitmap in the array
419  if (maFirstBytes[0] == 0x42 && maFirstBytes[1] == 0x41)
420  nOffset = 14;
421  else
422  nOffset = 0;
423 
424  // Now we initially test on 'BM'
425  if (maFirstBytes[0 + nOffset] == 0x42 && maFirstBytes[1 + nOffset] == 0x4d)
426  {
427  // OS/2 can set the Reserved flags to a value other than 0
428  // (which they really should not do...);
429  // In this case we test the size of the BmpInfoHeaders
430  if ((maFirstBytes[6 + nOffset] == 0x00 && maFirstBytes[7 + nOffset] == 0x00
431  && maFirstBytes[8 + nOffset] == 0x00 && maFirstBytes[9 + nOffset] == 0x00)
432  || maFirstBytes[14 + nOffset] == 0x28 || maFirstBytes[14 + nOffset] == 0x0c)
433  {
434  msDetectedFormat = "BMP";
435  return true;
436  }
437  }
438  return false;
439 }
440 
442 {
443  if (mnFirstLong == 0xd7cdc69a || mnFirstLong == 0x01000900)
444  {
445  msDetectedFormat = "WMF";
446  return true;
447  }
448  else if (mnFirstLong == 0x01000000 && maFirstBytes[40] == 0x20 && maFirstBytes[41] == 0x45
449  && maFirstBytes[42] == 0x4d && maFirstBytes[43] == 0x46)
450  {
451  msDetectedFormat = "EMF";
452  return true;
453  }
454  return false;
455 }
456 
458 {
459  if (maFirstBytes[0] != 0x0a)
460  return false;
461 
463  sal_uInt8 nEncoding = maFirstBytes[2];
464  if ((nVersion == 0 || nVersion == 2 || nVersion == 3 || nVersion == 5) && nEncoding <= 1)
465  {
466  msDetectedFormat = "PCX";
467  return true;
468  }
469 
470  return false;
471 }
472 
474 {
475  if (mnFirstLong == 0x49492a00 || mnFirstLong == 0x4d4d002a)
476  {
477  msDetectedFormat = "TIF";
478  return true;
479  }
480  return false;
481 }
482 
484 {
485  if (mnFirstLong == 0x47494638 && (maFirstBytes[4] == 0x37 || maFirstBytes[4] == 0x39)
486  && maFirstBytes[5] == 0x61)
487  {
488  msDetectedFormat = "GIF";
489  return true;
490  }
491  return false;
492 }
493 
495 {
496  if (mnFirstLong == 0x89504e47 && mnSecondLong == 0x0d0a1a0a)
497  {
498  msDetectedFormat = "PNG";
499  return true;
500  }
501  return false;
502 }
503 
505 {
506  if ((mnFirstLong == 0xffd8ffe0 && maFirstBytes[6] == 0x4a && maFirstBytes[7] == 0x46
507  && maFirstBytes[8] == 0x49 && maFirstBytes[9] == 0x46)
508  || (mnFirstLong == 0xffd8fffe) || (0xffd8ff00 == (mnFirstLong & 0xffffff00)))
509  {
510  msDetectedFormat = "JPG";
511  return true;
512  }
513  return false;
514 }
515 
517 {
518  if (mnFirstLong == 0x53564744 && maFirstBytes[4] == 0x49)
519  {
520  msDetectedFormat = "SVM";
521  return true;
522  }
523  else if (maFirstBytes[0] == 0x56 && maFirstBytes[1] == 0x43 && maFirstBytes[2] == 0x4C
524  && maFirstBytes[3] == 0x4D && maFirstBytes[4] == 0x54 && maFirstBytes[5] == 0x46)
525  {
526  msDetectedFormat = "SVM";
527  return true;
528  }
529  return false;
530 }
531 
533 {
534  if (mnStreamLength < 2055)
535  return false;
536  char sBuffer[8];
538  sBuffer[mrStream.ReadBytes(sBuffer, 7)] = 0;
539 
540  if (strncmp(sBuffer, "PCD_IPI", 7) == 0)
541  {
542  msDetectedFormat = "PCD";
543  return true;
544  }
545  return false;
546 }
547 
549 {
550  if ((mnFirstLong == 0x38425053) && ((mnSecondLong >> 16) == 1))
551  {
552  msDetectedFormat = "PSD";
553  return true;
554  }
555  return false;
556 }
557 
559 {
560  const char* pFirstBytesAsCharArray = reinterpret_cast<char*>(maFirstBytes.data());
561 
562  if (mnFirstLong == 0xC5D0D3C6)
563  {
564  msDetectedFormat = "EPS";
565  return true;
566  }
567  else if (checkArrayForMatchingStrings(pFirstBytesAsCharArray, 30, { "%!PS-Adobe", " EPS" }))
568  {
569  msDetectedFormat = "EPS";
570  return true;
571  }
572 
573  return false;
574 }
575 
577 {
578  if (strncmp(reinterpret_cast<char*>(maFirstBytes.data()), "AutoCAD Binary DXF", 18) == 0)
579  {
580  msDetectedFormat = "DXF";
581  return true;
582  }
583 
584  // ASCII DXF File Format
585  int i = 0;
586  while (i < 256 && maFirstBytes[i] <= 32)
587  {
588  ++i;
589  }
590 
591  if (i < 256 && maFirstBytes[i] == '0')
592  {
593  ++i;
594 
595  // only now do we have sufficient data to make a judgement
596  // based on a '0' + 'SECTION' == DXF argument
597 
598  while (i < 256 && maFirstBytes[i] <= 32)
599  {
600  ++i;
601  }
602 
603  if (i + 7 < 256
604  && (strncmp(reinterpret_cast<char*>(maFirstBytes.data() + i), "SECTION", 7) == 0))
605  {
606  msDetectedFormat = "DXF";
607  return true;
608  }
609  }
610  return false;
611 }
612 
614 {
616  {
617  msDetectedFormat = "PCT";
618  return true;
619  }
620  return false;
621 }
622 
624 {
625  if (maFirstBytes[0] == 'P')
626  {
627  switch (maFirstBytes[1])
628  {
629  case '1':
630  case '4':
631  msDetectedFormat = "PBM";
632  return true;
633 
634  case '2':
635  case '5':
636  msDetectedFormat = "PGM";
637  return true;
638 
639  case '3':
640  case '6':
641  msDetectedFormat = "PPM";
642  return true;
643  }
644  }
645  return false;
646 }
647 
649 {
650  if (mnFirstLong == 0x59a66a95)
651  {
652  msDetectedFormat = "RAS";
653  return true;
654  }
655  return false;
656 }
657 
659 {
660  const char* pFirstBytesAsCharArray = reinterpret_cast<char*>(maFirstBytes.data());
661  if (matchArrayWithString(pFirstBytesAsCharArray, 256, "/* XPM */"))
662  {
663  msDetectedFormat = "XPM";
664  return true;
665  }
666  return false;
667 }
668 
670 {
671  sal_uInt64 nSize = std::min<sal_uInt64>(mnStreamLength, 2048);
672  std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nSize]);
673 
675  nSize = mrStream.ReadBytes(pBuffer.get(), nSize);
676 
677  const char* pBufferAsCharArray = reinterpret_cast<char*>(pBuffer.get());
678 
679  if (checkArrayForMatchingStrings(pBufferAsCharArray, nSize, { "#define", "_width" }))
680  {
681  msDetectedFormat = "XBM";
682  return true;
683  }
684  return false;
685 }
686 
688 {
689  sal_uInt8* pCheckArray = maFirstBytes.data();
690  sal_uInt64 nCheckSize = std::min<sal_uInt64>(mnStreamLength, 256);
691 
692  sal_uInt8 sExtendedOrDecompressedFirstBytes[2048];
693  sal_uInt64 nDecompressedSize = nCheckSize;
694 
695  bool bIsGZip(false);
696 
697  // check if it is gzipped -> svgz
698  if (maFirstBytes[0] == 0x1F && maFirstBytes[1] == 0x8B)
699  {
700  ZCodec aCodec;
702  aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/ true);
703  auto nDecompressedOut = aCodec.Read(mrStream, sExtendedOrDecompressedFirstBytes, 2048);
704  // ZCodec::Decompress returns -1 on failure
705  nDecompressedSize = nDecompressedOut < 0 ? 0 : nDecompressedOut;
706  nCheckSize = std::min<sal_uInt64>(nDecompressedSize, 256);
707  aCodec.EndCompression();
708  pCheckArray = sExtendedOrDecompressedFirstBytes;
709 
710  bIsGZip = true;
711  }
712 
713  bool bIsSvg(false);
714 
715  const char* pCheckArrayAsCharArray = reinterpret_cast<char*>(pCheckArray);
716 
717  // check for XML
718  // #119176# SVG files which have no xml header at all have shown up this is optional
719  // check for "xml" then "version" then "DOCTYPE" and "svg" tags
720  if (checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize,
721  { "<?xml", "version", "DOCTYPE", "svg" }))
722  {
723  bIsSvg = true;
724  }
725 
726  // check for svg element in 1st 256 bytes
727  // search for '<svg'
728  if (!bIsSvg && checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize, { "<svg" }))
729  {
730  bIsSvg = true;
731  }
732 
733  // extended search for svg element
734  if (!bIsSvg)
735  {
736  // it's a xml, look for '<svg' in full file. Should not happen too
737  // often since the tests above will handle most cases, but can happen
738  // with Svg files containing big comment headers or Svg as the host
739  // language
740 
741  pCheckArrayAsCharArray = reinterpret_cast<char*>(sExtendedOrDecompressedFirstBytes);
742 
743  if (bIsGZip)
744  {
745  nCheckSize = std::min<sal_uInt64>(nDecompressedSize, 2048);
746  }
747  else
748  {
749  nCheckSize = std::min<sal_uInt64>(mnStreamLength, 2048);
751  nCheckSize = mrStream.ReadBytes(sExtendedOrDecompressedFirstBytes, nCheckSize);
752  }
753 
754  // search for '<svg'
755  if (checkArrayForMatchingStrings(pCheckArrayAsCharArray, nCheckSize, { "<svg" }))
756  {
757  bIsSvg = true;
758  }
759  }
760 
761  if (bIsSvg)
762  {
763  msDetectedFormat = "SVG";
764  return true;
765  }
766  return false;
767 }
768 
770 {
771  // Check TGA ver.2 footer bytes
772  if (mnStreamLength > 18)
773  {
774  char sFooterBytes[18];
775 
777  mrStream.SeekRel(-18);
778  if (mrStream.ReadBytes(sFooterBytes, 18) == 18
779  && memcmp(sFooterBytes, "TRUEVISION-XFILE.", SAL_N_ELEMENTS(sFooterBytes)) == 0)
780  {
781  msDetectedFormat = "TGA";
782  return true;
783  }
784  }
785 
786  // Fallback to file extension check
787  if (maExtension.startsWith("TGA"))
788  {
789  msDetectedFormat = "TGA";
790  return true;
791  }
792  return false;
793 }
794 
796 {
797  if ((maFirstBytes[4] == 'f' && maFirstBytes[5] == 't' && maFirstBytes[6] == 'y'
798  && maFirstBytes[7] == 'p' && maFirstBytes[8] == 'q' && maFirstBytes[9] == 't')
799  || (maFirstBytes[4] == 'm' && maFirstBytes[5] == 'o' && maFirstBytes[6] == 'o'
800  && maFirstBytes[7] == 'v' && maFirstBytes[11] == 'l' && maFirstBytes[12] == 'm'))
801  {
802  msDetectedFormat = "MOV";
803  return true;
804  }
805  return false;
806 }
807 
809 {
810  if (maFirstBytes[0] == '%' && maFirstBytes[1] == 'P' && maFirstBytes[2] == 'D'
811  && maFirstBytes[3] == 'F' && maFirstBytes[4] == '-')
812  {
813  msDetectedFormat = "PDF";
814  return true;
815  }
816  return false;
817 }
818 
819 } // vcl namespace
820 
821 /* 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)
bool good() const
SvStreamEndian