summaryrefslogtreecommitdiff
path: root/filter/source/graphicfilter/itiff
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/graphicfilter/itiff')
-rw-r--r--filter/source/graphicfilter/itiff/ccidecom.cxx1112
-rw-r--r--filter/source/graphicfilter/itiff/ccidecom.hxx125
-rw-r--r--filter/source/graphicfilter/itiff/exports.map7
-rw-r--r--filter/source/graphicfilter/itiff/itiff.cxx1342
-rw-r--r--filter/source/graphicfilter/itiff/lzwdecom.cxx192
-rw-r--r--filter/source/graphicfilter/itiff/lzwdecom.hxx79
-rw-r--r--filter/source/graphicfilter/itiff/makefile.mk71
7 files changed, 2928 insertions, 0 deletions
diff --git a/filter/source/graphicfilter/itiff/ccidecom.cxx b/filter/source/graphicfilter/itiff/ccidecom.cxx
new file mode 100644
index 000000000000..5e9e75cbf815
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/ccidecom.cxx
@@ -0,0 +1,1112 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+
+#include "ccidecom.hxx"
+
+//=============================== Huffman-Tabellen ========================
+
+//---------------------------- White-Run ------------------------------
+
+#define CCIWhiteTableSize 105
+
+const CCIHuffmanTableEntry CCIWhiteTable[CCIWhiteTableSize]={
+ { 0, 0x0035, 8 },
+ { 1, 0x0007, 6 },
+ { 2, 0x0007, 4 },
+ { 3, 0x0008, 4 },
+ { 4, 0x000b, 4 },
+ { 5, 0x000c, 4 },
+ { 6, 0x000e, 4 },
+ { 7, 0x000f, 4 },
+ { 8, 0x0013, 5 },
+ { 9, 0x0014, 5 },
+ { 10, 0x0007, 5 },
+ { 11, 0x0008, 5 },
+ { 12, 0x0008, 6 },
+ { 13, 0x0003, 6 },
+ { 14, 0x0034, 6 },
+ { 15, 0x0035, 6 },
+ { 16, 0x002a, 6 },
+ { 17, 0x002b, 6 },
+ { 18, 0x0027, 7 },
+ { 19, 0x000c, 7 },
+ { 20, 0x0008, 7 },
+ { 21, 0x0017, 7 },
+ { 22, 0x0003, 7 },
+ { 23, 0x0004, 7 },
+ { 24, 0x0028, 7 },
+ { 25, 0x002b, 7 },
+ { 26, 0x0013, 7 },
+ { 27, 0x0024, 7 },
+ { 28, 0x0018, 7 },
+ { 29, 0x0002, 8 },
+ { 30, 0x0003, 8 },
+ { 31, 0x001a, 8 },
+ { 32, 0x001b, 8 },
+ { 33, 0x0012, 8 },
+ { 34, 0x0013, 8 },
+ { 35, 0x0014, 8 },
+ { 36, 0x0015, 8 },
+ { 37, 0x0016, 8 },
+ { 38, 0x0017, 8 },
+ { 39, 0x0028, 8 },
+ { 40, 0x0029, 8 },
+ { 41, 0x002a, 8 },
+ { 42, 0x002b, 8 },
+ { 43, 0x002c, 8 },
+ { 44, 0x002d, 8 },
+ { 45, 0x0004, 8 },
+ { 46, 0x0005, 8 },
+ { 47, 0x000a, 8 },
+ { 48, 0x000b, 8 },
+ { 49, 0x0052, 8 },
+ { 50, 0x0053, 8 },
+ { 51, 0x0054, 8 },
+ { 52, 0x0055, 8 },
+ { 53, 0x0024, 8 },
+ { 54, 0x0025, 8 },
+ { 55, 0x0058, 8 },
+ { 56, 0x0059, 8 },
+ { 57, 0x005a, 8 },
+ { 58, 0x005b, 8 },
+ { 59, 0x004a, 8 },
+ { 60, 0x004b, 8 },
+ { 61, 0x0032, 8 },
+ { 62, 0x0033, 8 },
+ { 63, 0x0034, 8 },
+ { 64, 0x001b, 5 },
+ { 128, 0x0012, 5 },
+ { 192, 0x0017, 6 },
+ { 256, 0x0037, 7 },
+ { 320, 0x0036, 8 },
+ { 384, 0x0037, 8 },
+ { 448, 0x0064, 8 },
+ { 512, 0x0065, 8 },
+ { 576, 0x0068, 8 },
+ { 640, 0x0067, 8 },
+ { 704, 0x00cc, 9 },
+ { 768, 0x00cd, 9 },
+ { 832, 0x00d2, 9 },
+ { 896, 0x00d3, 9 },
+ { 960, 0x00d4, 9 },
+ { 1024, 0x00d5, 9 },
+ { 1088, 0x00d6, 9 },
+ { 1152, 0x00d7, 9 },
+ { 1216, 0x00d8, 9 },
+ { 1280, 0x00d9, 9 },
+ { 1344, 0x00da, 9 },
+ { 1408, 0x00db, 9 },
+ { 1472, 0x0098, 9 },
+ { 1536, 0x0099, 9 },
+ { 1600, 0x009a, 9 },
+ { 1664, 0x0018, 6 },
+ { 1728, 0x009b, 9 },
+ { 1792, 0x0008, 11 },
+ { 1856, 0x000c, 11 },
+ { 1920, 0x000d, 11 },
+ { 1984, 0x0012, 12 },
+ { 2048, 0x0013, 12 },
+ { 2112, 0x0014, 12 },
+ { 2176, 0x0015, 12 },
+ { 2240, 0x0016, 12 },
+ { 2304, 0x0017, 12 },
+ { 2368, 0x001c, 12 },
+ { 2432, 0x001d, 12 },
+ { 2496, 0x001e, 12 },
+ { 2560, 0x001f, 12 },
+ { 9999, 0x0001, 12 } // EOL
+};
+
+//---------------------------- Black-Run ------------------------------
+
+#define CCIBlackTableSize 105
+
+const CCIHuffmanTableEntry CCIBlackTable[CCIBlackTableSize]={
+ { 0, 0x0037, 10 },
+ { 1, 0x0002, 3 },
+ { 2, 0x0003, 2 },
+ { 3, 0x0002, 2 },
+ { 4, 0x0003, 3 },
+ { 5, 0x0003, 4 },
+ { 6, 0x0002, 4 },
+ { 7, 0x0003, 5 },
+ { 8, 0x0005, 6 },
+ { 9, 0x0004, 6 },
+ { 10, 0x0004, 7 },
+ { 11, 0x0005, 7 },
+ { 12, 0x0007, 7 },
+ { 13, 0x0004, 8 },
+ { 14, 0x0007, 8 },
+ { 15, 0x0018, 9 },
+ { 16, 0x0017, 10 },
+ { 17, 0x0018, 10 },
+ { 18, 0x0008, 10 },
+ { 19, 0x0067, 11 },
+ { 20, 0x0068, 11 },
+ { 21, 0x006c, 11 },
+ { 22, 0x0037, 11 },
+ { 23, 0x0028, 11 },
+ { 24, 0x0017, 11 },
+ { 25, 0x0018, 11 },
+ { 26, 0x00ca, 12 },
+ { 27, 0x00cb, 12 },
+ { 28, 0x00cc, 12 },
+ { 29, 0x00cd, 12 },
+ { 30, 0x0068, 12 },
+ { 31, 0x0069, 12 },
+ { 32, 0x006a, 12 },
+ { 33, 0x006b, 12 },
+ { 34, 0x00d2, 12 },
+ { 35, 0x00d3, 12 },
+ { 36, 0x00d4, 12 },
+ { 37, 0x00d5, 12 },
+ { 38, 0x00d6, 12 },
+ { 39, 0x00d7, 12 },
+ { 40, 0x006c, 12 },
+ { 41, 0x006d, 12 },
+ { 42, 0x00da, 12 },
+ { 43, 0x00db, 12 },
+ { 44, 0x0054, 12 },
+ { 45, 0x0055, 12 },
+ { 46, 0x0056, 12 },
+ { 47, 0x0057, 12 },
+ { 48, 0x0064, 12 },
+ { 49, 0x0065, 12 },
+ { 50, 0x0052, 12 },
+ { 51, 0x0053, 12 },
+ { 52, 0x0024, 12 },
+ { 53, 0x0037, 12 },
+ { 54, 0x0038, 12 },
+ { 55, 0x0027, 12 },
+ { 56, 0x0028, 12 },
+ { 57, 0x0058, 12 },
+ { 58, 0x0059, 12 },
+ { 59, 0x002b, 12 },
+ { 60, 0x002c, 12 },
+ { 61, 0x005a, 12 },
+ { 62, 0x0066, 12 },
+ { 63, 0x0067, 12 },
+ { 64, 0x000f, 10 },
+ { 128, 0x00c8, 12 },
+ { 192, 0x00c9, 12 },
+ { 256, 0x005b, 12 },
+ { 320, 0x0033, 12 },
+ { 384, 0x0034, 12 },
+ { 448, 0x0035, 12 },
+ { 512, 0x006c, 13 },
+ { 576, 0x006d, 13 },
+ { 640, 0x004a, 13 },
+ { 704, 0x004b, 13 },
+ { 768, 0x004c, 13 },
+ { 832, 0x004d, 13 },
+ { 896, 0x0072, 13 },
+ { 960, 0x0073, 13 },
+ { 1024, 0x0074, 13 },
+ { 1088, 0x0075, 13 },
+ { 1152, 0x0076, 13 },
+ { 1216, 0x0077, 13 },
+ { 1280, 0x0052, 13 },
+ { 1344, 0x0053, 13 },
+ { 1408, 0x0054, 13 },
+ { 1472, 0x0055, 13 },
+ { 1536, 0x005a, 13 },
+ { 1600, 0x005b, 13 },
+ { 1664, 0x0064, 13 },
+ { 1728, 0x0065, 13 },
+ { 1792, 0x0008, 11 },
+ { 1856, 0x000c, 11 },
+ { 1920, 0x000d, 11 },
+ { 1984, 0x0012, 12 },
+ { 2048, 0x0013, 12 },
+ { 2112, 0x0014, 12 },
+ { 2176, 0x0015, 12 },
+ { 2240, 0x0016, 12 },
+ { 2304, 0x0017, 12 },
+ { 2368, 0x001c, 12 },
+ { 2432, 0x001d, 12 },
+ { 2496, 0x001e, 12 },
+ { 2560, 0x001f, 12 },
+ { 9999, 0x0001, 12 } // EOL
+};
+
+
+//---------------------------- 2D-Mode --------------------------------
+
+#define CCI2DMODE_UNCOMP 0
+#define CCI2DMODE_PASS 1
+#define CCI2DMODE_HORZ 2
+#define CCI2DMODE_VERT_L3 3
+#define CCI2DMODE_VERT_L2 4
+#define CCI2DMODE_VERT_L1 5
+#define CCI2DMODE_VERT_0 6
+#define CCI2DMODE_VERT_R1 7
+#define CCI2DMODE_VERT_R2 8
+#define CCI2DMODE_VERT_R3 9
+
+#define CCI2DModeTableSize 10
+
+const CCIHuffmanTableEntry CCI2DModeTable[CCI2DModeTableSize]={
+ { CCI2DMODE_UNCOMP , 0x000f, 10 },
+ { CCI2DMODE_PASS , 0x0001, 4 },
+ { CCI2DMODE_HORZ , 0x0001, 3 },
+ { CCI2DMODE_VERT_L3, 0x0002, 7 },
+ { CCI2DMODE_VERT_L2, 0x0002, 6 },
+ { CCI2DMODE_VERT_L1, 0x0002, 3 },
+ { CCI2DMODE_VERT_0 , 0x0001, 1 },
+ { CCI2DMODE_VERT_R1, 0x0003, 3 },
+ { CCI2DMODE_VERT_R2, 0x0003, 6 },
+ { CCI2DMODE_VERT_R3, 0x0003, 7 }
+};
+
+
+//-------------------------- 2D-Uncompressed-Mode ----------------------
+
+#define CCIUNCOMP_0White_1Black 0
+#define CCIUNCOMP_1White_1Black 1
+#define CCIUNCOMP_2White_1Black 2
+#define CCIUNCOMP_3White_1Black 3
+#define CCIUNCOMP_4White_1Black 4
+#define CCIUNCOMP_5White 5
+#define CCIUNCOMP_0White_End 6
+#define CCIUNCOMP_1White_End 7
+#define CCIUNCOMP_2White_End 8
+#define CCIUNCOMP_3White_End 9
+#define CCIUNCOMP_4White_End 10
+
+#define CCIUncompTableSize 11
+
+const CCIHuffmanTableEntry CCIUncompTable[CCIUncompTableSize]={
+ { CCIUNCOMP_0White_1Black, 0x0001, 1 },
+ { CCIUNCOMP_1White_1Black, 0x0001, 2 },
+ { CCIUNCOMP_2White_1Black, 0x0001, 3 },
+ { CCIUNCOMP_3White_1Black, 0x0001, 4 },
+ { CCIUNCOMP_4White_1Black, 0x0001, 5 },
+ { CCIUNCOMP_5White , 0x0001, 6 },
+ { CCIUNCOMP_0White_End , 0x0001, 7 },
+ { CCIUNCOMP_1White_End , 0x0001, 8 },
+ { CCIUNCOMP_2White_End , 0x0001, 9 },
+ { CCIUNCOMP_3White_End , 0x0001, 10 },
+ { CCIUNCOMP_4White_End , 0x0001, 11 }
+};
+
+
+//================== Sicherheitskopie der Huffman-Tabellen ================
+// Um sicher zugehen, dass die Huffman-Tabellen keine Fehler enthalten,
+// wurden sie zweimal von unterschiedlichen Quellen eingegeben (Uff) und
+// verglichen.
+// Da sich aber im Laufe der Pflege des Source-Codes mal ein Fehler
+// einschleichen koennte (z.B. versehentlicher druck einer Taste im Editor)
+// werden die Tablellen hier weiterhin zweimal aufgefuehrt und zur Laufzeit
+// verglichen. (Wenn der Vergleich fehlschlaegt, liefert CCIDecompressor
+// immer einen Fehler). Das Ganze mag etwas wahnsinnig erscheinen, aber ein Fehler
+// in den Tabellen waere sonst sehr sehr schwer zu erkennen, zumal es
+// unwahrscheinlich ist, dass eine oder mehere Beispieldateien alle Codes
+// durchlaufen.
+
+const CCIHuffmanTableEntry CCIWhiteTableSave[CCIWhiteTableSize]={
+ { 0, 0x0035, 8 },
+ { 1, 0x0007, 6 },
+ { 2, 0x0007, 4 },
+ { 3, 0x0008, 4 },
+ { 4, 0x000b, 4 },
+ { 5, 0x000c, 4 },
+ { 6, 0x000e, 4 },
+ { 7, 0x000f, 4 },
+ { 8, 0x0013, 5 },
+ { 9, 0x0014, 5 },
+ { 10, 0x0007, 5 },
+ { 11, 0x0008, 5 },
+ { 12, 0x0008, 6 },
+ { 13, 0x0003, 6 },
+ { 14, 0x0034, 6 },
+ { 15, 0x0035, 6 },
+ { 16, 0x002a, 6 },
+ { 17, 0x002b, 6 },
+ { 18, 0x0027, 7 },
+ { 19, 0x000c, 7 },
+ { 20, 0x0008, 7 },
+ { 21, 0x0017, 7 },
+ { 22, 0x0003, 7 },
+ { 23, 0x0004, 7 },
+ { 24, 0x0028, 7 },
+ { 25, 0x002b, 7 },
+ { 26, 0x0013, 7 },
+ { 27, 0x0024, 7 },
+ { 28, 0x0018, 7 },
+ { 29, 0x0002, 8 },
+ { 30, 0x0003, 8 },
+ { 31, 0x001a, 8 },
+ { 32, 0x001b, 8 },
+ { 33, 0x0012, 8 },
+ { 34, 0x0013, 8 },
+ { 35, 0x0014, 8 },
+ { 36, 0x0015, 8 },
+ { 37, 0x0016, 8 },
+ { 38, 0x0017, 8 },
+ { 39, 0x0028, 8 },
+ { 40, 0x0029, 8 },
+ { 41, 0x002a, 8 },
+ { 42, 0x002b, 8 },
+ { 43, 0x002c, 8 },
+ { 44, 0x002d, 8 },
+ { 45, 0x0004, 8 },
+ { 46, 0x0005, 8 },
+ { 47, 0x000a, 8 },
+ { 48, 0x000b, 8 },
+ { 49, 0x0052, 8 },
+ { 50, 0x0053, 8 },
+ { 51, 0x0054, 8 },
+ { 52, 0x0055, 8 },
+ { 53, 0x0024, 8 },
+ { 54, 0x0025, 8 },
+ { 55, 0x0058, 8 },
+ { 56, 0x0059, 8 },
+ { 57, 0x005a, 8 },
+ { 58, 0x005b, 8 },
+ { 59, 0x004a, 8 },
+ { 60, 0x004b, 8 },
+ { 61, 0x0032, 8 },
+ { 62, 0x0033, 8 },
+ { 63, 0x0034, 8 },
+ { 64, 0x001b, 5 },
+ { 128, 0x0012, 5 },
+ { 192, 0x0017, 6 },
+ { 256, 0x0037, 7 },
+ { 320, 0x0036, 8 },
+ { 384, 0x0037, 8 },
+ { 448, 0x0064, 8 },
+ { 512, 0x0065, 8 },
+ { 576, 0x0068, 8 },
+ { 640, 0x0067, 8 },
+ { 704, 0x00cc, 9 },
+ { 768, 0x00cd, 9 },
+ { 832, 0x00d2, 9 },
+ { 896, 0x00d3, 9 },
+ { 960, 0x00d4, 9 },
+ { 1024, 0x00d5, 9 },
+ { 1088, 0x00d6, 9 },
+ { 1152, 0x00d7, 9 },
+ { 1216, 0x00d8, 9 },
+ { 1280, 0x00d9, 9 },
+ { 1344, 0x00da, 9 },
+ { 1408, 0x00db, 9 },
+ { 1472, 0x0098, 9 },
+ { 1536, 0x0099, 9 },
+ { 1600, 0x009a, 9 },
+ { 1664, 0x0018, 6 },
+ { 1728, 0x009b, 9 },
+ { 1792, 0x0008, 11 },
+ { 1856, 0x000c, 11 },
+ { 1920, 0x000d, 11 },
+ { 1984, 0x0012, 12 },
+ { 2048, 0x0013, 12 },
+ { 2112, 0x0014, 12 },
+ { 2176, 0x0015, 12 },
+ { 2240, 0x0016, 12 },
+ { 2304, 0x0017, 12 },
+ { 2368, 0x001c, 12 },
+ { 2432, 0x001d, 12 },
+ { 2496, 0x001e, 12 },
+ { 2560, 0x001f, 12 },
+ { 9999, 0x0001, 12 } // EOL
+};
+
+const CCIHuffmanTableEntry CCIBlackTableSave[CCIBlackTableSize]={
+ { 0, 0x0037, 10 },
+ { 1, 0x0002, 3 },
+ { 2, 0x0003, 2 },
+ { 3, 0x0002, 2 },
+ { 4, 0x0003, 3 },
+ { 5, 0x0003, 4 },
+ { 6, 0x0002, 4 },
+ { 7, 0x0003, 5 },
+ { 8, 0x0005, 6 },
+ { 9, 0x0004, 6 },
+ { 10, 0x0004, 7 },
+ { 11, 0x0005, 7 },
+ { 12, 0x0007, 7 },
+ { 13, 0x0004, 8 },
+ { 14, 0x0007, 8 },
+ { 15, 0x0018, 9 },
+ { 16, 0x0017, 10 },
+ { 17, 0x0018, 10 },
+ { 18, 0x0008, 10 },
+ { 19, 0x0067, 11 },
+ { 20, 0x0068, 11 },
+ { 21, 0x006c, 11 },
+ { 22, 0x0037, 11 },
+ { 23, 0x0028, 11 },
+ { 24, 0x0017, 11 },
+ { 25, 0x0018, 11 },
+ { 26, 0x00ca, 12 },
+ { 27, 0x00cb, 12 },
+ { 28, 0x00cc, 12 },
+ { 29, 0x00cd, 12 },
+ { 30, 0x0068, 12 },
+ { 31, 0x0069, 12 },
+ { 32, 0x006a, 12 },
+ { 33, 0x006b, 12 },
+ { 34, 0x00d2, 12 },
+ { 35, 0x00d3, 12 },
+ { 36, 0x00d4, 12 },
+ { 37, 0x00d5, 12 },
+ { 38, 0x00d6, 12 },
+ { 39, 0x00d7, 12 },
+ { 40, 0x006c, 12 },
+ { 41, 0x006d, 12 },
+ { 42, 0x00da, 12 },
+ { 43, 0x00db, 12 },
+ { 44, 0x0054, 12 },
+ { 45, 0x0055, 12 },
+ { 46, 0x0056, 12 },
+ { 47, 0x0057, 12 },
+ { 48, 0x0064, 12 },
+ { 49, 0x0065, 12 },
+ { 50, 0x0052, 12 },
+ { 51, 0x0053, 12 },
+ { 52, 0x0024, 12 },
+ { 53, 0x0037, 12 },
+ { 54, 0x0038, 12 },
+ { 55, 0x0027, 12 },
+ { 56, 0x0028, 12 },
+ { 57, 0x0058, 12 },
+ { 58, 0x0059, 12 },
+ { 59, 0x002b, 12 },
+ { 60, 0x002c, 12 },
+ { 61, 0x005a, 12 },
+ { 62, 0x0066, 12 },
+ { 63, 0x0067, 12 },
+ { 64, 0x000f, 10 },
+ { 128, 0x00c8, 12 },
+ { 192, 0x00c9, 12 },
+ { 256, 0x005b, 12 },
+ { 320, 0x0033, 12 },
+ { 384, 0x0034, 12 },
+ { 448, 0x0035, 12 },
+ { 512, 0x006c, 13 },
+ { 576, 0x006d, 13 },
+ { 640, 0x004a, 13 },
+ { 704, 0x004b, 13 },
+ { 768, 0x004c, 13 },
+ { 832, 0x004d, 13 },
+ { 896, 0x0072, 13 },
+ { 960, 0x0073, 13 },
+ { 1024, 0x0074, 13 },
+ { 1088, 0x0075, 13 },
+ { 1152, 0x0076, 13 },
+ { 1216, 0x0077, 13 },
+ { 1280, 0x0052, 13 },
+ { 1344, 0x0053, 13 },
+ { 1408, 0x0054, 13 },
+ { 1472, 0x0055, 13 },
+ { 1536, 0x005a, 13 },
+ { 1600, 0x005b, 13 },
+ { 1664, 0x0064, 13 },
+ { 1728, 0x0065, 13 },
+ { 1792, 0x0008, 11 },
+ { 1856, 0x000c, 11 },
+ { 1920, 0x000d, 11 },
+ { 1984, 0x0012, 12 },
+ { 2048, 0x0013, 12 },
+ { 2112, 0x0014, 12 },
+ { 2176, 0x0015, 12 },
+ { 2240, 0x0016, 12 },
+ { 2304, 0x0017, 12 },
+ { 2368, 0x001c, 12 },
+ { 2432, 0x001d, 12 },
+ { 2496, 0x001e, 12 },
+ { 2560, 0x001f, 12 },
+ { 9999, 0x0001, 12 } // EOL
+};
+
+
+const CCIHuffmanTableEntry CCI2DModeTableSave[CCI2DModeTableSize]={
+ { CCI2DMODE_UNCOMP , 0x000f, 10 },
+ { CCI2DMODE_PASS , 0x0001, 4 },
+ { CCI2DMODE_HORZ , 0x0001, 3 },
+ { CCI2DMODE_VERT_L3, 0x0002, 7 },
+ { CCI2DMODE_VERT_L2, 0x0002, 6 },
+ { CCI2DMODE_VERT_L1, 0x0002, 3 },
+ { CCI2DMODE_VERT_0 , 0x0001, 1 },
+ { CCI2DMODE_VERT_R1, 0x0003, 3 },
+ { CCI2DMODE_VERT_R2, 0x0003, 6 },
+ { CCI2DMODE_VERT_R3, 0x0003, 7 }
+};
+
+
+const CCIHuffmanTableEntry CCIUncompTableSave[CCIUncompTableSize]={
+ { CCIUNCOMP_0White_1Black, 0x0001, 1 },
+ { CCIUNCOMP_1White_1Black, 0x0001, 2 },
+ { CCIUNCOMP_2White_1Black, 0x0001, 3 },
+ { CCIUNCOMP_3White_1Black, 0x0001, 4 },
+ { CCIUNCOMP_4White_1Black, 0x0001, 5 },
+ { CCIUNCOMP_5White , 0x0001, 6 },
+ { CCIUNCOMP_0White_End , 0x0001, 7 },
+ { CCIUNCOMP_1White_End , 0x0001, 8 },
+ { CCIUNCOMP_2White_End , 0x0001, 9 },
+ { CCIUNCOMP_3White_End , 0x0001, 10 },
+ { CCIUNCOMP_4White_End , 0x0001, 11 }
+};
+
+//=========================================================================
+
+
+CCIDecompressor::CCIDecompressor( ULONG nOpts, UINT32 nImageWidth ) :
+ bTableBad ( FALSE ),
+ bStatus ( FALSE ),
+ pByteSwap ( NULL ),
+ nWidth ( nImageWidth ),
+ nOptions ( nOpts ),
+ pLastLine ( NULL )
+{
+ if ( nOpts & CCI_OPTION_INVERSEBITORDER )
+ {
+ pByteSwap = new BYTE[ 256 ];
+ for ( int i = 0; i < 256; i++ )
+ {
+ pByteSwap[ i ] = sal::static_int_cast< BYTE >(
+ ( i << 7 ) | ( ( i & 2 ) << 5 ) | ( ( i & 4 ) << 3 ) | ( ( i & 8 ) << 1 ) |
+ ( ( i & 16 ) >> 1 ) | ( ( i & 32 ) >> 3 ) | ( ( i & 64 ) >> 5 ) | ( ( i & 128 ) >> 7 ));
+ }
+ }
+
+ pWhiteLookUp =new CCILookUpTableEntry[1<<13];
+ pBlackLookUp =new CCILookUpTableEntry[1<<13];
+ p2DModeLookUp=new CCILookUpTableEntry[1<<10];
+ pUncompLookUp=new CCILookUpTableEntry[1<<11];
+
+ MakeLookUp(CCIWhiteTable,CCIWhiteTableSave,pWhiteLookUp,CCIWhiteTableSize,13);
+ MakeLookUp(CCIBlackTable,CCIBlackTableSave,pBlackLookUp,CCIBlackTableSize,13);
+ MakeLookUp(CCI2DModeTable,CCI2DModeTableSave,p2DModeLookUp,CCI2DModeTableSize,10);
+ MakeLookUp(CCIUncompTable,CCIUncompTableSave,pUncompLookUp,CCIUncompTableSize,11);
+}
+
+
+CCIDecompressor::~CCIDecompressor()
+{
+ delete[] pByteSwap;
+ delete[] pLastLine;
+ delete[] pWhiteLookUp;
+ delete[] pBlackLookUp;
+ delete[] p2DModeLookUp;
+ delete[] pUncompLookUp;
+}
+
+
+void CCIDecompressor::StartDecompression( SvStream & rIStream )
+{
+ pIStream = &rIStream;
+ nInputBitsBufSize = 0;
+ bFirstEOL = TRUE;
+ bStatus = TRUE;
+ nEOLCount = 0;
+
+ if ( bTableBad == TRUE )
+ return;
+}
+
+
+BOOL CCIDecompressor::DecompressScanline( BYTE * pTarget, ULONG nTargetBits )
+{
+ USHORT i;
+ BYTE * pSrc,* pDst;
+ BOOL b2D;
+
+ if ( nEOLCount >= 5 ) // RTC( Return To Controller )
+ return TRUE;
+
+ if ( bStatus == FALSE )
+ return FALSE;
+
+ // Wenn EOL-Codes vorhanden sind, steht der EOL-Code auch vor der ersten Zeile.
+ // (und ich dachte EOL heisst 'End Of Line'...)
+ // Daher lesen wir den EOL-Code immer vor jeder Zeile als erstes ein:
+ if ( nOptions & CCI_OPTION_EOL )
+ {
+ if ( bFirstEOL )
+ {
+ UINT32 nCurPos = pIStream->Tell();
+ UINT16 nOldInputBitsBufSize = nInputBitsBufSize;
+ UINT32 nOldInputBitsBuf = nInputBitsBuf;
+ if ( ReadEOL( 32 ) == FALSE )
+ {
+ nInputBitsBufSize = nOldInputBitsBufSize;
+ nInputBitsBuf = nOldInputBitsBuf;
+ pIStream->Seek( nCurPos );
+ nOptions &=~ CCI_OPTION_EOL; // CCITT Group 3 - Compression Type 2
+ }
+ bFirstEOL = FALSE;
+ }
+ else
+ {
+ if ( ReadEOL( nTargetBits ) == FALSE )
+ {
+ return bStatus;
+ }
+ }
+ }
+
+ if ( nEOLCount >= 5 ) // RTC( Return To Controller )
+ return TRUE;
+
+ // ggf. eine weisse vorherige Zeile herstellen fuer 2D:
+ if ( nOptions & CCI_OPTION_2D )
+ {
+ if ( pLastLine == NULL || nLastLineSize != ( ( nTargetBits + 7 ) >> 3 ) )
+ {
+ if ( pLastLine == NULL )
+ delete[] pLastLine;
+ nLastLineSize = ( nTargetBits + 7 ) >> 3;
+ pLastLine = new BYTE[ nLastLineSize ];
+ pDst = pLastLine;
+ for ( i = 0; i < nLastLineSize; i++ ) *( pDst++ ) = 0x00;
+ }
+ }
+ // ggf. Zeilen-Anfang auf naechste Byte-Grenze runden:
+ if ( nOptions & CCI_OPTION_BYTEALIGNROW )
+ nInputBitsBufSize &= 0xfff8;
+
+ // Ist es eine 2D-Zeile ?:
+ if ( nOptions & CCI_OPTION_2D )
+ {
+ if ( nOptions & CCI_OPTION_EOL )
+ b2D = Read2DTag();
+ else
+ b2D = TRUE;
+ }
+ else
+ b2D = FALSE;
+
+ // Zeile einlesen:
+ if ( b2D )
+ Read2DScanlineData( pTarget, (USHORT)nTargetBits );
+ else
+ Read1DScanlineData( pTarget, (USHORT)nTargetBits );
+
+ // Wenn wir im 2D-Modus sind, muessen wir uns die Zeile merken:
+ if ( nOptions & CCI_OPTION_2D && bStatus == TRUE )
+ {
+ pSrc = pTarget;
+ pDst = pLastLine;
+ for ( i = 0; i < nLastLineSize; i++ ) *(pDst++)=*(pSrc++);
+ }
+
+ if ( pIStream->GetError() )
+ bStatus = FALSE;
+
+ return bStatus;
+}
+
+
+void CCIDecompressor::MakeLookUp(const CCIHuffmanTableEntry * pHufTab,
+ const CCIHuffmanTableEntry * pHufTabSave,
+ CCILookUpTableEntry * pLookUp,
+ USHORT nHuffmanTableSize,
+ USHORT nMaxCodeBits)
+{
+ USHORT i,j,nMinCode,nMaxCode,nLookUpSize,nMask;
+
+ if (bTableBad==TRUE) return;
+
+ nLookUpSize=1<<nMaxCodeBits;
+
+ nMask=0xffff>>(16-nMaxCodeBits);
+
+ for (i=0; i<nLookUpSize; i++) pLookUp[i].nCodeBits=0;
+ for (i=0; i<nHuffmanTableSize; i++) {
+ if ( pHufTab[i].nValue!=pHufTabSave[i].nValue ||
+ pHufTab[i].nCode!=pHufTabSave[i].nCode ||
+ pHufTab[i].nCodeBits!=pHufTabSave[i].nCodeBits ||
+ pHufTab[i].nCodeBits==0 ||
+ pHufTab[i].nCodeBits>nMaxCodeBits )
+ {
+ bTableBad=TRUE;
+ return;
+ }
+ nMinCode = nMask & (pHufTab[i].nCode << (nMaxCodeBits-pHufTab[i].nCodeBits));
+ nMaxCode = nMinCode | (nMask >> pHufTab[i].nCodeBits);
+ for (j=nMinCode; j<=nMaxCode; j++) {
+ if (pLookUp[j].nCodeBits!=0) {
+ bTableBad=TRUE;
+ return;
+ }
+ pLookUp[j].nValue=pHufTab[i].nValue;
+ pLookUp[j].nCodeBits=pHufTab[i].nCodeBits;
+ }
+ }
+}
+
+
+BOOL CCIDecompressor::ReadEOL( UINT32 /*nMaxFillBits*/ )
+{
+ USHORT nCode;
+ BYTE nByte;
+
+ // if (nOptions&CCI_OPTION_BYTEALIGNEOL) nMaxFillBits=7; else nMaxFillBits=0;
+ // Buuuh: Entweder wird die Option in itiff.cxx nicht richtig gesetzt (-> Fehler in Doku)
+ // oder es gibt tatsaechlich gemeine Export-Filter, die immer ein Align machen.
+ // Ausserdem wurden Dateien gefunden, in denen mehr als die maximal 7 noetigen
+ // Fuellbits vor dem EOL-Code stehen. Daher akzeptieren wir nun grundsaetzlich
+ // bis zu 32-Bloedsinn-Bits vor dem EOL-Code:
+ // und ich habe eine Datei gefunden in der bis zu ??? Bloedsinn Bits stehen, zudem ist dort die Bit Reihenfolge verdreht (SJ);
+
+ UINT32 nMaxPos = pIStream->Tell();
+ nMaxPos += nWidth >> 3;
+
+ for ( ;; )
+ {
+ while ( nInputBitsBufSize < 12 )
+ {
+ *pIStream >> nByte;
+ if ( pIStream->IsEof() )
+ return FALSE;
+ if ( pIStream->Tell() > nMaxPos )
+ return FALSE;
+
+ if ( nOptions & CCI_OPTION_INVERSEBITORDER )
+ nByte = pByteSwap[ nByte ];
+ nInputBitsBuf=(nInputBitsBuf<<8) | (ULONG)nByte;
+ nInputBitsBufSize += 8;
+ }
+ nCode = (USHORT)( ( nInputBitsBuf >> ( nInputBitsBufSize - 12 ) ) & 0x0fff );
+ if ( nCode == 0x0001 )
+ {
+ nEOLCount++;
+ nInputBitsBufSize -= 12;
+ break;
+ }
+ else
+ nInputBitsBufSize--;
+ }
+ return TRUE;
+}
+
+
+BOOL CCIDecompressor::Read2DTag()
+{
+ BYTE nByte;
+
+ // Ein Bit einlesen und TRUE liefern, wenn es 0 ist, sonst FALSE
+ if (nInputBitsBufSize==0) {
+ *pIStream >> nByte;
+ if ( nOptions & CCI_OPTION_INVERSEBITORDER )
+ nByte = pByteSwap[ nByte ];
+ nInputBitsBuf=(ULONG)nByte;
+ nInputBitsBufSize=8;
+ }
+ nInputBitsBufSize--;
+ if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return FALSE;
+ else return TRUE;
+}
+
+
+BYTE CCIDecompressor::ReadBlackOrWhite()
+{
+ BYTE nByte;
+
+ // Ein Bit einlesen und 0x00 liefern, wenn es 0 ist, sonst 0xff
+ if (nInputBitsBufSize==0) {
+ *pIStream >> nByte;
+ if ( nOptions & CCI_OPTION_INVERSEBITORDER )
+ nByte = pByteSwap[ nByte ];
+ nInputBitsBuf=(ULONG)nByte;
+ nInputBitsBufSize=8;
+ }
+ nInputBitsBufSize--;
+ if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return 0xff;
+ else return 0x00;
+}
+
+
+USHORT CCIDecompressor::ReadCodeAndDecode(const CCILookUpTableEntry * pLookUp,
+ USHORT nMaxCodeBits)
+{
+ USHORT nCode,nCodeBits;
+ BYTE nByte;
+
+ // Einen Huffman-Code einlesen und dekodieren:
+ while (nInputBitsBufSize<nMaxCodeBits) {
+ *pIStream >> nByte;
+ if ( nOptions & CCI_OPTION_INVERSEBITORDER )
+ nByte = pByteSwap[ nByte ];
+ nInputBitsBuf=(nInputBitsBuf<<8) | (ULONG)nByte;
+ nInputBitsBufSize+=8;
+ }
+ nCode=(USHORT)((nInputBitsBuf>>(nInputBitsBufSize-nMaxCodeBits))
+ &(0xffff>>(16-nMaxCodeBits)));
+ nCodeBits=pLookUp[nCode].nCodeBits;
+ if (nCodeBits==0) bStatus=FALSE;
+ nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
+ return pLookUp[nCode].nValue;
+}
+
+
+void CCIDecompressor::FillBits(BYTE * pTarget, USHORT nTargetBits,
+ USHORT nBitPos, USHORT nNumBits,
+ BYTE nBlackOrWhite)
+{
+ if ( nBitPos >= nTargetBits )
+ return;
+ if ( nBitPos + nNumBits > nTargetBits )
+ nNumBits = nTargetBits - nBitPos;
+
+ pTarget+=nBitPos>>3;
+ nBitPos&=7;
+
+ if (nBlackOrWhite==0x00) *pTarget &= 0xff << (8-nBitPos);
+ else *pTarget |= 0xff >> nBitPos;
+ if (nNumBits>8-nBitPos) {
+ nNumBits-=8-nBitPos;
+ while (nNumBits>=8) {
+ *(++pTarget)=nBlackOrWhite;
+ nNumBits-=8;
+ }
+ if (nNumBits>0) *(++pTarget)=nBlackOrWhite;
+ }
+}
+
+
+USHORT CCIDecompressor::CountBits(const BYTE * pData, USHORT nDataSizeBits,
+ USHORT nBitPos, BYTE nBlackOrWhite)
+{
+ USHORT nPos,nLo;
+ BYTE nData;
+
+ // Hier wird die Anzahl der zusammenhaengenden Bits gezaehlt, die
+ // ab Position nBitPos in pTarget alle die Farbe nBlackOrWhite
+ // (0xff oder 0x00) haben.
+
+ nPos=nBitPos;
+ for (;;) {
+ if (nPos>=nDataSizeBits) {
+ nPos=nDataSizeBits;
+ break;
+ }
+ nData=pData[nPos>>3];
+ nLo=nPos & 7;
+ if ( nLo==0 && nData==nBlackOrWhite) nPos+=8;
+ else {
+ if ( ((nData^nBlackOrWhite) & (0x80 >> nLo))!=0) break;
+ nPos++;
+ }
+ }
+ if (nPos<=nBitPos) return 0;
+ else return nPos-nBitPos;
+}
+
+
+void CCIDecompressor::Read1DScanlineData(BYTE * pTarget, USHORT nTargetBits)
+{
+ USHORT nCode,nCodeBits,nDataBits,nTgtFreeByteBits;
+ BYTE nByte;
+ BYTE nBlackOrWhite; // ist 0xff fuer Black oder 0x00 fuer White
+ BOOL bTerminatingCode;
+
+ // Der erste Code ist immer eine "White-Code":
+ nBlackOrWhite=0x00;
+
+ // Anzahl der Bits, die im Byte *pTarget noch nicht geschrieben sind:
+ nTgtFreeByteBits=8;
+
+ // Schleife ueber Codes aus dem Eingabe-Stream:
+ do {
+
+ // die naechsten 13 Bits nach nCode holen, aber noch nicht
+ // aus dem Eingabe-Buffer loeschen:
+ while (nInputBitsBufSize<13) {
+ *pIStream >> nByte;
+ if ( nOptions & CCI_OPTION_INVERSEBITORDER )
+ nByte = pByteSwap[ nByte ];
+ nInputBitsBuf=(nInputBitsBuf<<8) | (ULONG)nByte;
+ nInputBitsBufSize+=8;
+ }
+ nCode=(USHORT)((nInputBitsBuf>>(nInputBitsBufSize-13))&0x1fff);
+
+ // Anzahl der DatenBits und Anzahl der CodeBits ermitteln:
+ if (nBlackOrWhite) {
+ nCodeBits=pBlackLookUp[nCode].nCodeBits;
+ nDataBits=pBlackLookUp[nCode].nValue;
+ }
+ else {
+ nCodeBits=pWhiteLookUp[nCode].nCodeBits;
+ nDataBits=pWhiteLookUp[nCode].nValue;
+ }
+ // Ist es ein Ungueltiger Code ?
+ if ( nDataBits == 9999 )
+ {
+ return;
+ }
+ if ( nCodeBits == 0 )
+ {
+ return; // das koennen sich jetzt um FuellBits handeln
+ }
+ nEOLCount = 0;
+ // Zuviele Daten ?
+ if (nDataBits>nTargetBits) {
+ // Ja, koennte ein Folge-Fehler durch ungueltigen Code sein,
+ // daher irdenwie weitermachen:
+ nDataBits=nTargetBits;
+ }
+
+ // Ist es ein 'Terminating-Code' ?
+ if (nDataBits<64) bTerminatingCode=TRUE; else bTerminatingCode=FALSE;
+
+ // Die gelesenen Bits aus dem Eingabe-Buffer entfernen:
+ nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
+
+ // Die Anzahl Daten-Bits in die Scanline schreiben:
+ if (nDataBits>0) {
+ nTargetBits = nTargetBits - nDataBits;
+ if (nBlackOrWhite==0x00) *pTarget &= 0xff << nTgtFreeByteBits;
+ else *pTarget |= 0xff >> (8-nTgtFreeByteBits);
+ if (nDataBits<=nTgtFreeByteBits) {
+ if (nDataBits==nTgtFreeByteBits) {
+ pTarget++;
+ nTgtFreeByteBits=8;
+ }
+ else nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
+ }
+ else {
+ nDataBits = nDataBits - nTgtFreeByteBits;
+ pTarget++;
+ nTgtFreeByteBits=8;
+ while (nDataBits>=8) {
+ *(pTarget++)=nBlackOrWhite;
+ nDataBits-=8;
+ }
+ if (nDataBits>0) {
+ *pTarget=nBlackOrWhite;
+ nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
+ }
+ }
+ }
+
+ // ggf. Umschaltung Black <-> White:
+ if (bTerminatingCode==TRUE) nBlackOrWhite=~nBlackOrWhite;
+
+ } while (nTargetBits>0 || bTerminatingCode==FALSE);
+}
+
+
+
+void CCIDecompressor::Read2DScanlineData(BYTE * pTarget, USHORT nTargetBits)
+{
+ USHORT n2DMode,nBitPos,nUncomp,nRun,nRun2,nt;
+ BYTE nBlackOrWhite;
+
+ nBlackOrWhite=0x00;
+ nBitPos=0;
+
+ while (nBitPos<nTargetBits && bStatus==TRUE) {
+
+ n2DMode=ReadCodeAndDecode(p2DModeLookUp,10);
+ if (bStatus==FALSE) return;
+
+ if (n2DMode==CCI2DMODE_UNCOMP) {
+ for (;;) {
+ nUncomp=ReadCodeAndDecode(pUncompLookUp,11);
+ if ( nUncomp <= CCIUNCOMP_4White_1Black ) {
+ nRun=nUncomp-CCIUNCOMP_0White_1Black;
+ FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
+ nBitPos = nBitPos + nRun;
+ FillBits(pTarget,nTargetBits,nBitPos,1,0xff);
+ nBitPos++;
+ }
+ else if ( nUncomp == CCIUNCOMP_5White ) {
+ FillBits(pTarget,nTargetBits,nBitPos,5,0x00);
+ nBitPos = nBitPos + 5;
+ }
+ else {
+ nRun=nUncomp-CCIUNCOMP_0White_End;
+ FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
+ nBitPos = nBitPos + nRun;
+ nBlackOrWhite=ReadBlackOrWhite();
+ break;
+ }
+ }
+ }
+
+ else if (n2DMode==CCI2DMODE_PASS) {
+ if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
+ else {
+ nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
+ nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
+ }
+ nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,~nBlackOrWhite);
+ FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
+ nBitPos = nBitPos + nRun;
+ }
+
+ else if (n2DMode==CCI2DMODE_HORZ) {
+ if (nBlackOrWhite==0x00) {
+ nRun=0;
+ do {
+ nt=ReadCodeAndDecode(pWhiteLookUp,13);
+ nRun = nRun + nt;
+ } while (nt>=64);
+ nRun2=0;
+ do {
+ nt=ReadCodeAndDecode(pBlackLookUp,13);
+ nRun2 = nRun2 + nt;
+ } while (nt>=64);
+ }
+ else {
+ nRun=0;
+ do {
+ nt=ReadCodeAndDecode(pBlackLookUp,13);
+ nRun = nRun + nt;
+ } while (nt>=64);
+ nRun2=0;
+ do {
+ nt=ReadCodeAndDecode(pWhiteLookUp,13);
+ nRun2 = nRun2 + nt;
+ } while (nt>=64);
+ }
+ FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
+ nBitPos = nBitPos + nRun;
+ FillBits(pTarget,nTargetBits,nBitPos,nRun2,~nBlackOrWhite);
+ nBitPos = nBitPos + nRun2;
+ }
+
+ else { // Es ist einer der Modi CCI2DMODE_VERT_...
+ if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
+ else {
+ nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
+ nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
+ }
+ nRun+=n2DMode-CCI2DMODE_VERT_0;
+ FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
+ nBitPos = nBitPos + nRun;
+ nBlackOrWhite=~nBlackOrWhite;
+ }
+ }
+}
+
+
diff --git a/filter/source/graphicfilter/itiff/ccidecom.hxx b/filter/source/graphicfilter/itiff/ccidecom.hxx
new file mode 100644
index 000000000000..2543be82d052
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/ccidecom.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CCIDECOM_HXX
+#define _CCIDECOM_HXX
+
+#include <tools/stream.hxx>
+
+
+#define CCI_OPTION_2D 1 // 2D-Komprimierung (statt 1D)
+#define CCI_OPTION_EOL 2 // EOL-Codes am Ende jeder Zeile vorhanden
+#define CCI_OPTION_BYTEALIGNEOL 4 // Fuellbits vor jedem EOL-Code, so dass
+ // Ende von EOL auf Bytes aligend
+#define CCI_OPTION_BYTEALIGNROW 8 // Rows beginnen immer auf Byte-Grenze
+#define CCI_OPTION_INVERSEBITORDER 16
+
+// Eintrag in eine Huffman-Tabelle:
+struct CCIHuffmanTableEntry {
+ USHORT nValue; // Der Daten-Wert.
+ USHORT nCode; // Der Code durch den der Daten-Wert repraesentiert wird.
+ USHORT nCodeBits; // Laenge des Codes in Bits.
+};
+
+
+// Eintrag in eine Hash-Tabelle zur schnellen Dekodierung
+struct CCILookUpTableEntry {
+ USHORT nValue;
+ USHORT nCodeBits;
+};
+
+
+class CCIDecompressor {
+
+public:
+
+ CCIDecompressor( ULONG nOptions, UINT32 nImageWidth );
+ ~CCIDecompressor();
+
+ void StartDecompression( SvStream & rIStream );
+
+ BOOL DecompressScanline(BYTE * pTarget, ULONG nTargetBits );
+
+private:
+
+ void MakeLookUp(const CCIHuffmanTableEntry * pHufTab,
+ const CCIHuffmanTableEntry * pHufTabSave,
+ CCILookUpTableEntry * pLookUp,
+ USHORT nHuffmanTableSize,
+ USHORT nMaxCodeBits);
+
+ BOOL ReadEOL( UINT32 nMaxFillBits );
+
+ BOOL Read2DTag();
+
+ BYTE ReadBlackOrWhite();
+
+ USHORT ReadCodeAndDecode(const CCILookUpTableEntry * pLookUp,
+ USHORT nMaxCodeBits);
+
+ void FillBits(BYTE * pTarget, USHORT nTargetBits,
+ USHORT nBitPos, USHORT nNumBits,
+ BYTE nBlackOrWhite);
+
+ USHORT CountBits(const BYTE * pData, USHORT nDataSizeBits,
+ USHORT nBitPos, BYTE nBlackOrWhite);
+
+ void Read1DScanlineData(BYTE * pTarget, USHORT nTargetBits);
+
+ void Read2DScanlineData(BYTE * pTarget, USHORT nTargetBits);
+
+ BOOL bTableBad;
+
+ BOOL bStatus;
+
+ BYTE* pByteSwap;
+
+ SvStream * pIStream;
+
+ UINT32 nEOLCount;
+
+ UINT32 nWidth;
+
+ ULONG nOptions;
+
+ BOOL bFirstEOL;
+
+ CCILookUpTableEntry * pWhiteLookUp;
+ CCILookUpTableEntry * pBlackLookUp;
+ CCILookUpTableEntry * p2DModeLookUp;
+ CCILookUpTableEntry * pUncompLookUp;
+
+ ULONG nInputBitsBuf;
+ USHORT nInputBitsBufSize;
+
+ BYTE * pLastLine;
+ ULONG nLastLineSize;
+};
+
+
+#endif
+
diff --git a/filter/source/graphicfilter/itiff/exports.map b/filter/source/graphicfilter/itiff/exports.map
new file mode 100644
index 000000000000..941e4ab9bde8
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/exports.map
@@ -0,0 +1,7 @@
+UDK_3_0_0 {
+ global:
+ GraphicImport;
+
+ local:
+ *;
+};
diff --git a/filter/source/graphicfilter/itiff/itiff.cxx b/filter/source/graphicfilter/itiff/itiff.cxx
new file mode 100644
index 000000000000..5ad400fc3149
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/itiff.cxx
@@ -0,0 +1,1342 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+#include <vcl/graph.hxx>
+#include <vcl/bmpacc.hxx>
+#ifndef _SV_FLTCALL_HXX
+#include <svtools/fltcall.hxx>
+#endif
+#include <vcl/animate.hxx>
+#include "lzwdecom.hxx"
+#include "ccidecom.hxx"
+
+#define OOODEBUG(str,Num) //(InfoBox(NULL,String(str)+String(" ")+String(Num)).Execute();
+
+namespace {
+
+template< typename T > T BYTESWAP(T nByte) {
+ return ( nByte << 7 ) | ( ( nByte & 2 ) << 5 ) | ( ( nByte & 4 ) << 3 ) |
+ ( ( nByte & 8 ) << 1 ) | ( ( nByte & 16 ) >> 1 ) |
+ ( ( nByte & 32 ) >> 3 ) | ( ( nByte & 64 ) >> 5 ) |
+ ( ( nByte & 128 ) >> 7 );
+}
+
+}
+
+//============================ TIFFReader ==================================
+
+class TIFFReader
+{
+
+private:
+
+ BOOL bStatus; // Ob bisher kein Fehler auftrat
+ Animation aAnimation;
+ ULONG nLastPercent;
+
+ SvStream* pTIFF; // Die einzulesende TIFF-Datei
+ Bitmap aBitmap;
+ BitmapWriteAccess* pAcc;
+ USHORT nDstBitsPerPixel;
+
+ ULONG nOrigPos; // Anfaengliche Position in pTIFF
+ UINT16 nOrigNumberFormat; // Anfaengliches Nummern-Format von pTIFF
+
+
+ UINT16 nDataType;
+ // Daten, die aus dem TIFF-Tags entnommen werden:
+ BOOL bByteSwap; // TRUE wenn bits 0..7 -> 7..0 invertiert werden sollen ( FILLORDER = 2 );
+ BYTE nByte1; // 'I', wenn Format LittleEndian
+
+ ULONG nNewSubFile; //
+ ULONG nSubFile; //
+ ULONG nImageWidth; // Bildbreite in Pixel
+ ULONG nImageLength; // Bildhoehe in Pixel
+ ULONG nBitsPerSample; // Bits pro Pixel pro Ebene
+ ULONG nCompression; // Art der Kompriemierung
+ ULONG nPhotometricInterpretation; //
+ ULONG nThresholding; //
+ ULONG nCellWidth; //
+ ULONG nCellLength; //
+ ULONG nFillOrder; //
+ ULONG* pStripOffsets; // Feld von Offsets zu den Bitmap-Daten-"Strips"
+ ULONG nNumStripOffsets; // Groesse obigen Feldes
+ ULONG nOrientation; //
+ ULONG nSamplesPerPixel; // Anzahl der Ebenen
+ ULONG nRowsPerStrip; // Wenn nicht komprimiert: Zahl der Zeilen pro Strip
+ ULONG* pStripByteCounts; // Wenn komprimiert (bestimmte Art): Groesse der Strips
+ ULONG nNumStripByteCounts; // Anzahl der Eintraege in obiges Feld
+ ULONG nMinSampleValue; //
+ ULONG nMaxSampleValue; //
+ double fXResolution; // X-Aufloesung oder 0.0
+ double fYResolution; // Y-Aufloesung oder 0.0
+ ULONG nPlanarConfiguration; //
+ ULONG nGroup3Options; //
+ ULONG nGroup4Options; //
+ ULONG nResolutionUnit; // Einheit von fX/YResolution: 1=unbekannt, 2(default)=Zoll, 3=cm
+ ULONG nPredictor; //
+ ULONG* pColorMap; // Farb-Palette
+ ULONG nNumColors; // Anzahl Farben in der Farbpalette
+
+ ULONG nPlanes; // Anzahl der Ebenen in der Tiff-Datei
+ ULONG nStripsPerPlane; // Anzahl der Strips pro Ebene
+ ULONG nBytesPerRow; // Bytes pro Zeile pro Ebene in der Tiff-Datei ( unkomprimiert )
+ BYTE* pMap[ 4 ]; // Temporaere Scanline
+
+
+ void MayCallback( ULONG nPercent );
+
+ ULONG DataTypeSize();
+ ULONG ReadIntData();
+ double ReadDoubleData();
+
+ void ReadHeader();
+ void ReadTagData( USHORT nTagType, sal_uInt32 nDataLen );
+
+ BOOL ReadMap( ULONG nMinPercent, ULONG nMaxPercent );
+ // Liesst/dekomprimert die Bitmap-Daten, und fuellt pMap
+
+ ULONG GetBits( const BYTE * pSrc, ULONG nBitsPos, ULONG nBitsCount );
+ // Holt nBitsCount Bits aus pSrc[..] an der Bit-Position nBitsPos
+
+ void MakePalCol( void );
+ // Erzeugt die Bitmap aus der temporaeren Bitmap pMap
+ // und loescht dabei pMap teilweise
+ BOOL ConvertScanline( ULONG nY );
+ // Konvertiert eine Scanline in das Windows-BMP-Format
+
+public:
+
+ TIFFReader() {}
+ ~TIFFReader() {}
+
+ BOOL ReadTIFF( SvStream & rTIFF, Graphic & rGraphic );
+};
+
+//=================== Methoden von TIFFReader ==============================
+
+void TIFFReader::MayCallback( ULONG /*nPercent*/ )
+{
+/*
+ if ( nPercent >= nLastPercent + 3 )
+ {
+ nLastPercent=nPercent;
+ if ( pCallback != NULL && nPercent <= 100 && bStatus == TRUE )
+ {
+ if (((*pCallback)(pCallerData,(USHORT)nPercent)) == TRUE )
+ bStatus = FALSE;
+ }
+ }
+*/
+}
+
+// ---------------------------------------------------------------------------------
+
+ULONG TIFFReader::DataTypeSize()
+{
+ ULONG nSize;
+ switch ( nDataType )
+ {
+ case 1 : // BYTE
+ case 2 : // ACSII
+ case 6 : // SIGNED Byte
+ case 7 : // UNDEFINED
+ nSize = 1;
+ break;
+ case 3 : // UINT16
+ case 8 : // INT16
+ nSize = 2;
+ break;
+ case 4 : // UINT32
+ case 9 : // INT32
+ case 11 : // FLOAT
+ nSize = 4;
+ break;
+ case 5 : // RATIONAL
+ case 10 : // SIGNED RATINAL
+ case 12 : // DOUBLE
+ nSize = 8;
+ break;
+ default:
+ pTIFF->SetError(SVSTREAM_FILEFORMAT_ERROR);
+ nSize=1;
+ }
+ return nSize;
+}
+
+// ---------------------------------------------------------------------------------
+
+ULONG TIFFReader::ReadIntData()
+{
+ double nDOUBLE;
+ float nFLOAT;
+ UINT32 nUINT32a, nUINT32b;
+ INT32 nINT32;
+ UINT16 nUINT16;
+ INT16 nINT16;
+ BYTE nBYTE;
+ char nCHAR;
+
+ switch( nDataType )
+ {
+ case 0 : //??
+ case 1 :
+ case 2 :
+ case 7 :
+ *pTIFF >> nBYTE;
+ nUINT32a = (ULONG)nBYTE;
+ break;
+ case 3 :
+ *pTIFF >> nUINT16;
+ nUINT32a = (ULONG)nUINT16;
+ break;
+ case 9 :
+ case 4 :
+ *pTIFF >> nUINT32a;
+ break;
+ case 5 :
+ *pTIFF >> nUINT32a >> nUINT32b;
+ if ( nUINT32b != 0 )
+ nUINT32a /= nUINT32b;
+ break;
+ case 6 :
+ *pTIFF >> nCHAR;
+ nUINT32a = (INT32)nCHAR;
+ break;
+ case 8 :
+ *pTIFF >> nINT16;
+ nUINT32a = (INT32)nINT16;
+ break;
+ case 10 :
+ *pTIFF >> nUINT32a >> nINT32;
+ if ( nINT32 != 0 )
+ nUINT32a /= nINT32;
+ break;
+ case 11 :
+ *pTIFF >> nFLOAT;
+ nUINT32a = (INT32)nFLOAT;
+ break;
+ case 12 :
+ *pTIFF >> nDOUBLE;
+ nUINT32a = (INT32)nDOUBLE;
+ break;
+ default:
+ *pTIFF >> nUINT32a;
+ break;
+ }
+ return nUINT32a;
+}
+
+// ---------------------------------------------------------------------------------
+
+double TIFFReader::ReadDoubleData()
+{
+ sal_uInt32 nulong;
+ double nd;
+
+ if ( nDataType == 5 )
+ {
+ *pTIFF >> nulong;
+ nd = (double)nulong;
+ *pTIFF >> nulong;
+ if ( nulong != 0 )
+ nd /= (double)nulong;
+ }
+ else
+ nd = (double)ReadIntData();
+ return nd;
+}
+
+// ---------------------------------------------------------------------------------
+
+void TIFFReader::ReadTagData( USHORT nTagType, sal_uInt32 nDataLen)
+{
+ if ( bStatus == FALSE )
+ return;
+
+ switch ( nTagType )
+ {
+ case 0x00fe: // New Sub File
+ nNewSubFile = ReadIntData();
+ OOODEBUG("NewSubFile",nNewSubFile);
+ break;
+
+ case 0x00ff: // Sub File
+ nSubFile = ReadIntData();
+ OOODEBUG("SubFile",nSubFile);
+ break;
+
+ case 0x0100: // Image Width
+ nImageWidth = ReadIntData();
+ OOODEBUG("ImageWidth",nImageWidth);
+ break;
+
+ case 0x0101: // Image Length
+ nImageLength = ReadIntData();
+ OOODEBUG("ImageLength",nImageLength);
+ break;
+
+ case 0x0102: // Bits Per Sample
+ nBitsPerSample = ReadIntData();
+ OOODEBUG("BitsPerSample",nBitsPerSample);
+ break;
+
+ case 0x0103: // Compression
+ nCompression = ReadIntData();
+ OOODEBUG("Compression",nCompression);
+ break;
+
+ case 0x0106: // Photometric Interpreation
+ nPhotometricInterpretation = ReadIntData();
+ OOODEBUG("PhotometricInterpretation",nPhotometricInterpretation);
+ break;
+
+ case 0x0107: // Thresholding
+ nThresholding = ReadIntData();
+ OOODEBUG("Thresholding",nThresholding);
+ break;
+
+ case 0x0108: // Cell Width
+ nCellWidth = ReadIntData();
+ break;
+
+ case 0x0109: // Cell Length
+ nCellLength = ReadIntData();
+ break;
+
+ case 0x010a: // Fill Order
+ nFillOrder = ReadIntData();
+ OOODEBUG("FillOrder",nFillOrder);
+ break;
+
+ case 0x0111: { // Strip Offset(s)
+ ULONG nOldNumSO, i, * pOldSO;
+ pOldSO = pStripOffsets;
+ if ( pOldSO == NULL )
+ nNumStripOffsets = 0;
+ nOldNumSO = nNumStripOffsets;
+ nDataLen += nOldNumSO;
+ if ( ( nDataLen > nOldNumSO ) && ( nDataLen < SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) )
+ {
+ nNumStripOffsets = nDataLen;
+ try
+ {
+ pStripOffsets = new ULONG[ nNumStripOffsets ];
+ }
+ catch (std::bad_alloc)
+ {
+ pStripOffsets = NULL;
+ nNumStripOffsets = 0;
+ }
+ if ( pStripOffsets )
+ {
+ for ( i = 0; i < nOldNumSO; i++ )
+ pStripOffsets[ i ] = pOldSO[ i ] + nOrigPos;
+ for ( i = nOldNumSO; i < nNumStripOffsets; i++ )
+ pStripOffsets[ i ] = ReadIntData() + nOrigPos;
+ }
+ delete[] pOldSO;
+ }
+ OOODEBUG("StripOffsets (Anzahl:)",nDataLen);
+ break;
+ }
+ case 0x0112: // Orientation
+ nOrientation = ReadIntData();
+ OOODEBUG("Orientation",nOrientation);
+ break;
+
+ case 0x0115: // Samples Per Pixel
+ nSamplesPerPixel = ReadIntData();
+ OOODEBUG("SamplesPerPixel",nSamplesPerPixel);
+ break;
+
+ case 0x0116: // Rows Per Strip
+ nRowsPerStrip = ReadIntData();
+ OOODEBUG("RowsPerStrip",nRowsPerStrip);
+ break;
+
+ case 0x0117: { // Strip Byte Counts
+ ULONG nOldNumSBC, i, * pOldSBC;
+ pOldSBC = pStripByteCounts;
+ if ( pOldSBC == NULL )
+ nNumStripByteCounts = 0; // Sicherheitshalber
+ nOldNumSBC = nNumStripByteCounts;
+ nDataLen += nOldNumSBC;
+ if ( ( nDataLen > nOldNumSBC ) && ( nDataLen < SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) )
+ {
+ nNumStripByteCounts = nDataLen;
+ try
+ {
+ pStripByteCounts = new ULONG[ nNumStripByteCounts ];
+ }
+ catch (std::bad_alloc)
+ {
+ pStripByteCounts = NULL;
+ nNumStripByteCounts = 0;
+ }
+ if ( pStripByteCounts )
+ {
+ for ( i = 0; i < nOldNumSBC; i++ )
+ pStripByteCounts[ i ] = pOldSBC[ i ];
+ for ( i = nOldNumSBC; i < nNumStripByteCounts; i++)
+ pStripByteCounts[ i ] = ReadIntData();
+ }
+ delete[] pOldSBC;
+ }
+ OOODEBUG("StripByteCounts (Anzahl:)",nDataLen);
+ break;
+ }
+ case 0x0118: // Min Sample Value
+ nMinSampleValue = ReadIntData();
+ OOODEBUG("MinSampleValue",nMinSampleValue);
+ break;
+
+ case 0x0119: // Max Sample Value
+ nMaxSampleValue = ReadIntData();
+ OOODEBUG("MaxSampleValue",nMaxSampleValue);
+ break;
+
+ case 0x011a: // X Resolution
+ fXResolution = ReadDoubleData();
+ break;
+
+ case 0x011b: // Y Resolution
+ fYResolution = ReadDoubleData();
+ break;
+
+ case 0x011c: // Planar Configuration
+ nPlanarConfiguration = ReadIntData();
+ OOODEBUG("PlanarConfiguration",nPlanarConfiguration);
+ break;
+
+ case 0x0124: // Group 3 Options
+ nGroup3Options = ReadIntData();
+ OOODEBUG("Group3Options",nGroup3Options);
+ break;
+
+ case 0x0125: // Group 4 Options
+ nGroup4Options = ReadIntData();
+ OOODEBUG("Group4Options",nGroup4Options);
+ break;
+
+ case 0x0128: // Resolution Unit
+ nResolutionUnit = ReadIntData();
+ break;
+
+ case 0x013d: // Predictor
+ nPredictor = ReadIntData();
+ OOODEBUG("Predictor",nPredictor);
+ break;
+
+ case 0x0140: { // Color Map
+ USHORT nVal;
+ ULONG i;
+ nNumColors= ( 1 << nBitsPerSample );
+ if ( nDataType == 3 && nNumColors <= 256)
+ {
+ pColorMap = new ULONG[ 256 ];
+ for ( i = 0; i < nNumColors; i++ )
+ pColorMap[ i ] = 0;
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ *pTIFF >> nVal;
+ pColorMap[ i ] |= ( ( (ULONG)nVal ) << 8 ) & 0x00ff0000;
+ }
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ *pTIFF >> nVal;
+ pColorMap[ i ] |= ( (ULONG)nVal ) & 0x0000ff00;
+ }
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ *pTIFF >> nVal;
+ pColorMap[ i ] |= ( ( (ULONG)nVal ) >> 8 ) & 0x000000ff;
+ }
+ }
+ else
+ bStatus = FALSE;
+ OOODEBUG("ColorMap (Anzahl Farben:)", nNumColors);
+ break;
+ }
+ }
+
+ if ( pTIFF->GetError() )
+ bStatus = FALSE;
+}
+
+// ---------------------------------------------------------------------------------
+
+BOOL TIFFReader::ReadMap( ULONG nMinPercent, ULONG nMaxPercent )
+{
+ if ( nCompression == 1 || nCompression == 32771 )
+ {
+ ULONG ny, np, nStrip, nStripBytesPerRow;
+
+ if ( nCompression == 1 )
+ nStripBytesPerRow = nBytesPerRow;
+ else
+ nStripBytesPerRow = ( nBytesPerRow + 1 ) & 0xfffffffe;
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ nStrip = ny / nRowsPerStrip + np * nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek( pStripOffsets[ nStrip ] + ( ny % nRowsPerStrip ) * nStripBytesPerRow );
+ pTIFF->Read( pMap[ np ], nBytesPerRow );
+ if ( pTIFF->GetError() )
+ return FALSE;
+ MayCallback( nMinPercent + ( nMaxPercent - nMinPercent ) * ( np * nImageLength + ny) / ( nImageLength * nPlanes ) );
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else if ( nCompression == 2 || nCompression == 3 || nCompression == 4 )
+ {
+ ULONG ny, np, nStrip, nOptions;
+ if ( nCompression == 2 )
+ {
+ nOptions = CCI_OPTION_BYTEALIGNROW;
+ }
+ else if ( nCompression == 3 )
+ {
+ nOptions = CCI_OPTION_EOL;
+ if ( nGroup3Options & 0x00000001 )
+ nOptions |= CCI_OPTION_2D;
+ if ( nGroup3Options & 0x00000004 )
+ nOptions |= CCI_OPTION_BYTEALIGNEOL;
+ if ( nGroup3Options & 0xfffffffa )
+ return FALSE;
+ }
+ else
+ { // nCompression==4
+ nOptions = CCI_OPTION_2D;
+ if ( nGroup4Options & 0xffffffff )
+ return FALSE;
+ }
+ if ( nFillOrder == 2 )
+ {
+ nOptions |= CCI_OPTION_INVERSEBITORDER;
+ bByteSwap = FALSE;
+ }
+ nStrip = 0;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+
+ CCIDecompressor aCCIDecom( nOptions, nImageWidth );
+
+ aCCIDecom.StartDecompression( *pTIFF );
+
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
+ {
+ nStrip=ny/nRowsPerStrip+np*nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek( pStripOffsets[ nStrip ] );
+ aCCIDecom.StartDecompression( *pTIFF );
+ }
+ if ( aCCIDecom.DecompressScanline( pMap[ np ], nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes ) == FALSE )
+ return FALSE;
+ if ( pTIFF->GetError() )
+ return FALSE;
+ MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else if ( nCompression == 5 )
+ {
+ LZWDecompressor aLZWDecom;
+ ULONG ny, np, nStrip;
+ nStrip=0;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ aLZWDecom.StartDecompression(*pTIFF);
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
+ {
+ nStrip = ny / nRowsPerStrip + np * nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ aLZWDecom.StartDecompression(*pTIFF);
+ }
+ if ( ( aLZWDecom.Decompress( pMap[ np ], nBytesPerRow ) != nBytesPerRow ) || pTIFF->GetError() )
+ return FALSE;
+ MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else if ( nCompression == 32773 )
+ {
+ ULONG nStrip,nRecCount,nRowBytesLeft,ny,np,i;
+ BYTE * pdst, nRecHeader, nRecData;
+ nStrip = 0;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
+ {
+ nStrip=ny/nRowsPerStrip+np*nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ }
+ nRowBytesLeft = nBytesPerRow;
+ pdst=pMap[ np ];
+ do
+ {
+ *pTIFF >> nRecHeader;
+ if ((nRecHeader&0x80)==0)
+ {
+ nRecCount=0x00000001+((ULONG)nRecHeader);
+ if ( nRecCount > nRowBytesLeft )
+ return FALSE;
+ pTIFF->Read(pdst,nRecCount);
+ pdst+=nRecCount;
+ nRowBytesLeft-=nRecCount;
+ }
+ else if ( nRecHeader != 0x80 )
+ {
+ nRecCount = 0x000000101 - ( (ULONG)nRecHeader );
+ if ( nRecCount > nRowBytesLeft )
+ {
+ nRecCount = nRowBytesLeft;
+
+// bStatus = FALSE;
+// return;
+
+ }
+ *pTIFF >> nRecData;
+ for ( i = 0; i < nRecCount; i++ )
+ *(pdst++) = nRecData;
+ nRowBytesLeft -= nRecCount;
+ }
+ } while ( nRowBytesLeft != 0 );
+ if ( pTIFF->GetError() )
+ return FALSE;
+ MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+ULONG TIFFReader::GetBits( const BYTE * pSrc, ULONG nBitsPos, ULONG nBitsCount )
+{
+ ULONG nRes;
+ if ( bByteSwap )
+ {
+ pSrc += ( nBitsPos >> 3 );
+ nBitsPos &= 7;
+ BYTE nDat = *pSrc;
+ nRes = (ULONG)( BYTESWAP( nDat ) & ( 0xff >> nBitsPos ) );
+
+ if ( nBitsCount <= 8 - nBitsPos )
+ {
+ nRes >>= ( 8 - nBitsPos - nBitsCount );
+ }
+ else
+ {
+ pSrc++;
+ nBitsCount -= 8 - nBitsPos;
+ while ( nBitsCount >= 8 )
+ {
+ nDat = *(pSrc++);
+ nRes = ( nRes << 8 ) | ((ULONG)BYTESWAP( nDat ) );
+ nBitsCount -= 8;
+ }
+ if ( nBitsCount > 0 )
+ {
+ nDat = *pSrc;
+ nRes = ( nRes << nBitsCount ) | (((ULONG)BYTESWAP(nDat))>>(8-nBitsCount));
+ }
+ }
+ }
+ else
+ {
+ pSrc += ( nBitsPos >> 3 );
+ nBitsPos &= 7;
+ nRes = (ULONG)((*pSrc)&(0xff>>nBitsPos));
+ if ( nBitsCount <= 8 - nBitsPos )
+ {
+ nRes >>= ( 8 - nBitsPos - nBitsCount );
+ }
+ else
+ {
+ pSrc++;
+ nBitsCount -= 8 - nBitsPos;
+ while ( nBitsCount >= 8 )
+ {
+ nRes = ( nRes << 8 ) | ((ULONG)*(pSrc++));
+ nBitsCount -= 8;
+ }
+ if ( nBitsCount > 0 )
+ nRes = ( nRes << nBitsCount ) | (((ULONG)*pSrc)>>(8-nBitsCount));
+ }
+ }
+ return nRes;
+}
+
+// ---------------------------------------------------------------------------------
+
+BOOL TIFFReader::ConvertScanline( ULONG nY )
+{
+ UINT32 nRed, nGreen, nBlue, ns, nx, nVal, nByteCount;
+ BYTE nByteVal;
+
+ if ( nDstBitsPerPixel == 24 )
+ {
+ if ( nBitsPerSample == 8 && nSamplesPerPixel >= 3 &&
+ nPlanes == 1 && nPhotometricInterpretation == 2 )
+ {
+ BYTE* pt = pMap[ 0 ];
+
+ // sind die Werte als Differenz abgelegt?
+ if ( 2 == nPredictor )
+ {
+ BYTE nLRed = 0;
+ BYTE nLGreen = 0;
+ BYTE nLBlue = 0;
+ for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel )
+ {
+ nLRed = nLRed + pt[ 0 ];
+ nLGreen = nLGreen + pt[ 1 ];
+ nLBlue = nLBlue + pt[ 2 ];
+ pAcc->SetPixel( nY, nx, Color( nLRed, nLGreen, nLBlue ) );
+ }
+ }
+ else
+ {
+ for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel )
+ {
+ pAcc->SetPixel( nY, nx, Color( pt[0], pt[1], pt[2] ) );
+ }
+ }
+ }
+ else if ( nPhotometricInterpretation == 2 && nSamplesPerPixel >= 3 )
+ {
+ ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ if ( nPlanes < 3 )
+ {
+ nRed = GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 1 ], ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 2 ], ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
+ }
+ else
+ {
+ nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample );
+ }
+ pAcc->SetPixel( nY, nx, Color( (BYTE)( nRed - nMinMax ), (BYTE)( nGreen - nMinMax ), (BYTE)(nBlue - nMinMax) ) );
+ }
+ }
+ else if ( nPhotometricInterpretation == 5 && nSamplesPerPixel == 3 )
+ {
+ ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ if ( nPlanes < 3 )
+ {
+ nRed = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
+ }
+ else
+ {
+ nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample );
+ }
+ nRed = 255 - (BYTE)( nRed - nMinMax );
+ nGreen = 255 - (BYTE)( nGreen - nMinMax );
+ nBlue = 255 - (BYTE)( nBlue - nMinMax );
+ pAcc->SetPixel( nY, nx, Color( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue ) );
+ }
+ }
+ else if( nPhotometricInterpretation == 5 && nSamplesPerPixel == 4 )
+ {
+ BYTE nSamp[ 4 ];
+ BYTE nSampLast[ 4 ] = { 0, 0, 0, 0 };
+ long nBlack;
+
+ for( nx = 0; nx < nImageWidth; nx++ )
+ {
+ // sind die Werte als Differenz abgelegt?
+ if( 2 == nPredictor )
+ {
+ for( ns = 0; ns < 4; ns++ )
+ {
+ if( nPlanes < 3 )
+ nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample );
+ else
+ nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample );
+ nSamp[ ns ] = nSampLast[ ns ];
+ }
+ }
+ else
+ {
+ for( ns = 0; ns < 4; ns++ )
+ {
+ if( nPlanes < 3 )
+ nSamp[ ns ] = (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample );
+ else
+ nSamp[ ns ]= (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample );
+ }
+ }
+ nBlack = nSamp[ 3 ];
+ nRed = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 0 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
+ 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
+ nGreen = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 1 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
+ 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
+ nBlue = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 2 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
+ 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
+ pAcc->SetPixel( nY, nx, Color ( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) );
+
+ }
+ }
+ }
+ else if ( nSamplesPerPixel == 1 && ( nPhotometricInterpretation <= 1 || nPhotometricInterpretation == 3 ) )
+ {
+ ULONG nMinMax = ( ( 1 << nDstBitsPerPixel ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
+ BYTE* pt = pMap[ 0 ];
+ BYTE nShift;
+
+ switch ( nDstBitsPerPixel )
+ {
+ case 8 :
+ {
+ BYTE nLast;
+ if ( bByteSwap )
+ {
+ if ( nPredictor == 2 )
+ {
+ nLast = BYTESWAP( (BYTE)*pt++ );
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ pAcc->SetPixel( nY, nx, nLast );
+ nLast = nLast + *pt++;
+ }
+ }
+ else
+ {
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ nLast = *pt++;
+ pAcc->SetPixel( nY, nx, (BYTE)( ( (BYTESWAP((ULONG)nLast ) - nMinSampleValue ) * nMinMax ) ) );
+ }
+ }
+ }
+ else
+ {
+ if ( nPredictor == 2 )
+ {
+ nLast = *pt++;
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ pAcc->SetPixel( nY, nx, nLast );
+ nLast = nLast + *pt++;
+ }
+ }
+ else
+ {
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt++ - nMinSampleValue ) * nMinMax ) );
+
+ }
+ }
+ }
+ }
+ break;
+
+ case 7 :
+ case 6 :
+ case 5 :
+ case 4 :
+ case 3 :
+ case 2 :
+ {
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax;
+ pAcc->SetPixel( nY, nx, (BYTE)nVal );
+ }
+ }
+ break;
+
+ case 1 :
+ {
+ if ( bByteSwap )
+ {
+ nx = 0;
+ nByteCount = ( nImageWidth >> 3 ) + 1;
+ while ( --nByteCount )
+ {
+ nByteVal = *pt++;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal );
+ }
+ if ( nImageWidth & 7 )
+ {
+ nByteVal = *pt++;
+ while ( nx < nImageWidth )
+ {
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ }
+ }
+ }
+ else
+ {
+ nx = 7;
+ nByteCount = ( nImageWidth >> 3 ) + 1;
+ while ( --nByteCount )
+ {
+ nByteVal = *pt++;
+ pAcc->SetPixel( nY, nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal );
+ nx += 15;
+ }
+ if ( nImageWidth & 7 )
+ {
+ nx -= 7;
+ nByteVal = *pt++;
+ nShift = 7;
+ while ( nx < nImageWidth )
+ {
+ pAcc->SetPixel( nY, nx++, ( nByteVal >> nShift ) & 1);
+ }
+ }
+ }
+ }
+ break;
+
+ default :
+ return FALSE;
+ }
+ }
+ else if ( ( nSamplesPerPixel == 2 ) && ( nBitsPerSample == 8 ) &&
+ ( nPlanarConfiguration == 1 ) && ( pColorMap == 0 ) ) // grayscale
+ {
+ ULONG nMinMax = ( ( 1 << 8 /*nDstBitsPerPixel*/ ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
+ BYTE* pt = pMap[ 0 ];
+ if ( nByte1 == 'I' )
+ pt++;
+ for ( nx = 0; nx < nImageWidth; nx++, pt += 2 )
+ {
+ pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt - nMinSampleValue ) * nMinMax ) );
+ }
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+// ---------------------------------------------------------------------------------
+
+void TIFFReader::MakePalCol( void )
+{
+ if ( nDstBitsPerPixel <= 8 )
+ {
+ ULONG i, nVal, n0RGB;
+ if ( pColorMap == NULL )
+ pColorMap = new ULONG[ 256 ];
+ if ( nPhotometricInterpretation <= 1 )
+ {
+ nNumColors = 1 << nBitsPerSample;
+ if ( nNumColors > 256 )
+ nNumColors = 256;
+ pAcc->SetPaletteEntryCount( (USHORT)nNumColors );
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ nVal = ( i * 255 / ( nNumColors - 1 ) ) & 0xff;
+ n0RGB = nVal | ( nVal << 8 ) | ( nVal << 16 );
+ if ( nPhotometricInterpretation == 1 )
+ pColorMap[ i ] = n0RGB;
+ else
+ pColorMap[ nNumColors - i - 1 ] = n0RGB;
+ }
+ }
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ pAcc->SetPaletteColor( (USHORT)i, BitmapColor( (BYTE)( pColorMap[ i ] >> 16 ),
+ (BYTE)( pColorMap[ i ] >> 8 ), (BYTE)pColorMap[ i ] ) );
+ }
+ }
+
+ if ( fXResolution > 1.0 && fYResolution > 1.0 && ( nResolutionUnit == 2 || nResolutionUnit == 3 ) )
+ {
+ ULONG nRX,nRY;
+ if (nResolutionUnit==2)
+ {
+ nRX=(ULONG)(fXResolution+0.5);
+ nRY=(ULONG)(fYResolution+0.5);
+ }
+ else
+ {
+ nRX=(ULONG)(fXResolution*2.54+0.5);
+ nRY=(ULONG)(fYResolution*2.54+0.5);
+ }
+ MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nRX),Fraction(1,nRY));
+ aBitmap.SetPrefMapMode(aMapMode);
+ aBitmap.SetPrefSize(Size(nImageWidth,nImageLength));
+ }
+}
+
+// ---------------------------------------------------------------------------------
+
+void TIFFReader::ReadHeader()
+{
+ BYTE nbyte1, nbyte2;
+ USHORT nushort;
+
+ *pTIFF >> nbyte1;
+ if ( nbyte1 == 'I' )
+ pTIFF->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ else
+ pTIFF->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+
+ *pTIFF >> nbyte2 >> nushort;
+ if ( nbyte1 != nbyte2 || ( nbyte1 != 'I' && nbyte1 != 'M' ) || nushort != 0x002a )
+ bStatus = FALSE;
+}
+
+// ---------------------------------------------------------------------------------
+
+BOOL TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic )
+{
+ USHORT i, nNumTags, nTagType;
+ ULONG nMaxPos;
+ ULONG nPos;
+ sal_uInt32 nFirstIfd, nDataLen;
+
+ bStatus = TRUE;
+ nLastPercent = 0;
+
+ pTIFF = &rTIFF;
+ nMaxPos = nOrigPos = pTIFF->Tell();
+ nOrigNumberFormat = pTIFF->GetNumberFormatInt();
+
+ MayCallback( 0 );
+
+ // Kopf einlesen:
+ ReadHeader();
+
+ // Ersten IFD einlesen:
+ *pTIFF >> nFirstIfd;
+
+ if( !nFirstIfd || pTIFF->GetError() )
+ bStatus = FALSE;
+
+ if ( bStatus )
+ {
+ sal_uInt32 nOffset = nFirstIfd;
+
+ // calculate length of TIFF file
+ do
+ {
+ pTIFF->Seek( nOrigPos + nOffset );
+
+ if( pTIFF->GetError() )
+ {
+ pTIFF->ResetError();
+ break;
+ };
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+
+ *pTIFF >> nNumTags;
+
+ // Schleife ueber Tags:
+ for( i = 0; i < nNumTags; i++ )
+ {
+ *pTIFF >> nTagType >> nDataType >> nDataLen >> nOffset;
+
+ if( DataTypeSize() * nDataLen > 4 )
+ nMaxPos = Max( nOrigPos + nOffset + DataTypeSize() * nDataLen, nMaxPos );
+ }
+ *pTIFF >> nOffset;
+ if ( pTIFF->IsEof() )
+ nOffset = 0;
+
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ if ( !nOffset )
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ }
+ while( nOffset );
+
+ for ( UINT32 nNextIfd = nFirstIfd; nNextIfd && bStatus; )
+ {
+ pTIFF->Seek( nOrigPos + nNextIfd );
+ {
+ bByteSwap = FALSE;
+
+ nNewSubFile = 0;
+ nSubFile = 0;
+ nImageWidth = 0;
+ nImageLength = 0;
+ nBitsPerSample = 1; // Defaultwert laut Doku
+ nCompression = 1;
+ nPhotometricInterpretation = 0;
+ nThresholding = 1; // Defaultwert laut Doku
+ nCellWidth = 1;
+ nCellLength = 1;
+ nFillOrder = 1; // Defaultwert laut Doku
+ nNumStripOffsets = 0;
+ nOrientation = 1;
+ nSamplesPerPixel = 1; // Defaultwert laut Doku
+ nRowsPerStrip = 0xffffffff; // Defaultwert laut Doku
+ nNumStripByteCounts = 0;
+ nMinSampleValue = 0; // Defaultwert laut Doku
+ nMaxSampleValue = 0;
+ fXResolution = 0.0;
+ fYResolution = 0.0;
+ nPlanarConfiguration = 1;
+ nGroup3Options = 0; // Defaultwert laut Doku
+ nGroup4Options = 0; // Defaultwert laut Doku
+ nResolutionUnit = 2; // Defaultwert laut Doku
+ nPredictor = 1;
+ nNumColors = 0;
+
+ pAcc = NULL;
+ pColorMap = NULL;
+ pStripOffsets = NULL;
+ pStripByteCounts = NULL;
+ pMap[ 0 ] = pMap[ 1 ] = pMap[ 2 ] = pMap[ 3 ] = NULL;
+
+ *pTIFF >> nNumTags;
+ nPos = pTIFF->Tell();
+
+ // Schleife ueber Tags:
+ for( i = 0; i < nNumTags; i++ )
+ {
+ *pTIFF >> nTagType >> nDataType >> nDataLen;
+
+ if( DataTypeSize() * nDataLen > 4 )
+ {
+ *pTIFF >> nOffset;
+ pTIFF->Seek( nOrigPos + nOffset );
+ }
+ ReadTagData( nTagType, nDataLen );
+ nPos += 12; pTIFF->Seek( nPos );
+
+ if ( pTIFF->GetError() )
+ bStatus = FALSE;
+
+ if ( bStatus == FALSE )
+ break;
+ }
+ *pTIFF >> nNextIfd;
+ if ( pTIFF->IsEof() )
+ nNextIfd = 0;
+ }
+ if ( bStatus )
+ {
+ if ( nMaxSampleValue == 0 )
+ nMaxSampleValue = ( 1 << nBitsPerSample ) - 1;
+
+ if ( nPhotometricInterpretation == 2 || nPhotometricInterpretation == 5 || nPhotometricInterpretation == 6 )
+ nDstBitsPerPixel = 24;
+ else if ( nBitsPerSample*nSamplesPerPixel <= 1 )
+ nDstBitsPerPixel = 1;
+ else if ( nBitsPerSample*nSamplesPerPixel <= 4 )
+ nDstBitsPerPixel = 4;
+ else
+ nDstBitsPerPixel = 8;
+
+ aBitmap = Bitmap( Size( nImageWidth, nImageLength ), nDstBitsPerPixel );
+ pAcc = aBitmap.AcquireWriteAccess();
+ if ( pAcc )
+ {
+ if ( nPlanarConfiguration == 1 )
+ nPlanes = 1;
+ else
+ nPlanes = nSamplesPerPixel;
+
+ if ( ( nFillOrder == 2 ) && ( nCompression != 5 ) ) // im LZW Mode werden die bits schon invertiert
+ bByteSwap = TRUE;
+
+ nStripsPerPlane = ( nImageLength - 1 ) / nRowsPerStrip + 1;
+ nBytesPerRow = ( nImageWidth * nSamplesPerPixel / nPlanes * nBitsPerSample + 7 ) >> 3;
+
+ for ( ULONG j = 0; j < 4; j++ )
+ {
+ try
+ {
+ pMap[ j ] = new BYTE[ nBytesPerRow ];
+ }
+ catch (std::bad_alloc)
+ {
+ pMap[ j ] = NULL;
+ bStatus = FALSE;
+ break;
+ }
+ }
+
+ if ( bStatus && ReadMap( 10, 60 ) )
+ {
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ MakePalCol();
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ }
+ else
+ bStatus = FALSE;
+
+ if( pAcc )
+ {
+ aBitmap.ReleaseAccess( pAcc );
+ if ( bStatus )
+ {
+ AnimationBitmap aAnimationBitmap( aBitmap, Point( 0, 0 ), aBitmap.GetSizePixel(),
+ ANIMATION_TIMEOUT_ON_CLICK, DISPOSE_BACK );
+
+ aAnimation.Insert( aAnimationBitmap );
+ }
+ }
+ // Aufraeumen:
+ for ( i = 0; i < 4; i++ )
+ delete[] pMap[ i ];
+
+ delete[] pColorMap;
+ delete[] pStripOffsets;
+ delete[] pStripByteCounts;
+ }
+ }
+ }
+ }
+
+ // seek to end of TIFF if succeeded
+ pTIFF->SetNumberFormatInt( nOrigNumberFormat );
+ pTIFF->Seek( bStatus ? nMaxPos : nOrigPos );
+
+ if ( aAnimation.Count() )
+ {
+ if ( aAnimation.Count() == 1 )
+ rGraphic = aAnimation.GetBitmapEx();
+ else
+ rGraphic = aAnimation; //aBitmap;
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+//================== GraphicImport - die exportierte Funktion ================
+
+extern "C" BOOL __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, BOOL )
+{
+ TIFFReader aTIFFReader;
+
+ if ( aTIFFReader.ReadTIFF( rStream, rGraphic ) == FALSE )
+ return FALSE;
+
+ return TRUE;
+}
+
+//============================= fuer Windows ==================================
+#ifndef GCC
+#endif
+
+#ifdef WIN
+
+static HINSTANCE hDLLInst = 0; // HANDLE der DLL
+
+extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
+{
+#ifndef WNT
+ if ( nHeap )
+ UnlockData( 0 );
+#endif
+
+ hDLLInst = hDLL;
+
+ return TRUE;
+}
+
+extern "C" int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+#endif
+
+
diff --git a/filter/source/graphicfilter/itiff/lzwdecom.cxx b/filter/source/graphicfilter/itiff/lzwdecom.cxx
new file mode 100644
index 000000000000..9460ed6ecf45
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/lzwdecom.cxx
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+
+#include "lzwdecom.hxx"
+
+LZWDecompressor::LZWDecompressor()
+{
+ USHORT i;
+
+ pTable=new LZWTableEntry[4096];
+ pOutBuf=new BYTE[4096];
+ for (i=0; i<4096; i++)
+ {
+ pTable[i].nPrevCode=0;
+ pTable[i].nDataCount=1;
+ pTable[i].nData=(BYTE)i;
+ }
+ pIStream=NULL;
+ bFirst = TRUE;
+ nOldCode = 0;
+}
+
+
+LZWDecompressor::~LZWDecompressor()
+{
+ delete[] pOutBuf;
+ delete[] pTable;
+}
+
+
+void LZWDecompressor::StartDecompression(SvStream & rIStream)
+{
+ pIStream=&rIStream;
+
+ nTableSize=258;
+
+ bEOIFound=FALSE;
+
+ nOutBufDataLen=0;
+
+ *pIStream >> nInputBitsBuf;
+
+ nInputBitsBufSize=8;
+
+ if ( bFirst )
+ {
+ bInvert = nInputBitsBuf == 1;
+ bFirst = FALSE;
+ }
+
+ if ( bInvert )
+ nInputBitsBuf = ( ( nInputBitsBuf & 1 ) << 7 ) | ( ( nInputBitsBuf & 2 ) << 5 ) | ( ( nInputBitsBuf & 4 ) << 3 ) | ( ( nInputBitsBuf & 8 ) << 1 ) | ( ( nInputBitsBuf & 16 ) >> 1 ) | ( ( nInputBitsBuf & 32 ) >> 3 ) | ( ( nInputBitsBuf & 64 ) >> 5 ) | ( (nInputBitsBuf & 128 ) >> 7 );
+}
+
+
+ULONG LZWDecompressor::Decompress(BYTE * pTarget, ULONG nMaxCount)
+{
+ ULONG nCount;
+
+ if (pIStream==NULL) return 0;
+
+ nCount=0;
+ for (;;) {
+
+ if (pIStream->GetError()) break;
+
+ if (((ULONG)nOutBufDataLen)>=nMaxCount) {
+ nOutBufDataLen = nOutBufDataLen - (USHORT)nMaxCount;
+ nCount+=nMaxCount;
+ while (nMaxCount>0) {
+ *(pTarget++)=*(pOutBufData++);
+ nMaxCount--;
+ }
+ break;
+ }
+
+ nMaxCount-=(ULONG)nOutBufDataLen;
+ nCount+=nOutBufDataLen;
+ while (nOutBufDataLen>0) {
+ *(pTarget++)=*(pOutBufData++);
+ nOutBufDataLen--;
+ }
+
+ if (bEOIFound==TRUE) break;
+
+ DecompressSome();
+
+ }
+
+ return nCount;
+}
+
+
+USHORT LZWDecompressor::GetNextCode()
+{
+ USHORT nBits,nCode;
+
+ if (nTableSize<511) nBits=9;
+ else if (nTableSize<1023) nBits=10;
+ else if (nTableSize<2047) nBits=11;
+ else nBits=12;
+
+ nCode=0;
+ do {
+ if (nInputBitsBufSize<=nBits)
+ {
+ nCode=(nCode<<nInputBitsBufSize) | nInputBitsBuf;
+ nBits = nBits - nInputBitsBufSize;
+ *pIStream >> nInputBitsBuf;
+ if ( bInvert )
+ nInputBitsBuf = ( ( nInputBitsBuf & 1 ) << 7 ) | ( ( nInputBitsBuf & 2 ) << 5 ) | ( ( nInputBitsBuf & 4 ) << 3 ) | ( ( nInputBitsBuf & 8 ) << 1 ) | ( ( nInputBitsBuf & 16 ) >> 1 ) | ( ( nInputBitsBuf & 32 ) >> 3 ) | ( ( nInputBitsBuf & 64 ) >> 5 ) | ( (nInputBitsBuf & 128 ) >> 7 );
+ nInputBitsBufSize=8;
+ }
+ else
+ {
+ nCode=(nCode<<nBits) | (nInputBitsBuf>>(nInputBitsBufSize-nBits));
+ nInputBitsBufSize = nInputBitsBufSize - nBits;
+ nInputBitsBuf&=0x00ff>>(8-nInputBitsBufSize);
+ nBits=0;
+ }
+ } while (nBits>0);
+
+ return nCode;
+}
+
+
+void LZWDecompressor::AddToTable(USHORT nPrevCode, USHORT nCodeFirstData)
+{
+ while (pTable[nCodeFirstData].nDataCount>1)
+ nCodeFirstData=pTable[nCodeFirstData].nPrevCode;
+
+ pTable[nTableSize].nPrevCode=nPrevCode;
+ pTable[nTableSize].nDataCount=pTable[nPrevCode].nDataCount+1;
+ pTable[nTableSize].nData=pTable[nCodeFirstData].nData;
+
+ nTableSize++;
+}
+
+
+void LZWDecompressor::DecompressSome()
+{
+ USHORT i,nCode;
+
+ nCode=GetNextCode();
+ if (nCode==256) {
+ nTableSize=258;
+ nCode=GetNextCode();
+ if (nCode==257) { bEOIFound=TRUE; return; }
+ }
+ else if (nCode<nTableSize) AddToTable(nOldCode,nCode);
+ else if (nCode==nTableSize) AddToTable(nOldCode,nOldCode);
+ else { bEOIFound=TRUE; return; }
+
+ nOldCode=nCode;
+
+ nOutBufDataLen=pTable[nCode].nDataCount;
+ pOutBufData=pOutBuf+nOutBufDataLen;
+ for (i=0; i<nOutBufDataLen; i++) {
+ *(--pOutBufData)=pTable[nCode].nData;
+ nCode=pTable[nCode].nPrevCode;
+ }
+}
+
+
+
diff --git a/filter/source/graphicfilter/itiff/lzwdecom.hxx b/filter/source/graphicfilter/itiff/lzwdecom.hxx
new file mode 100644
index 000000000000..164812878865
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/lzwdecom.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _LZWDECOM_HXX
+#define _LZWDECOM_HXX
+
+#include <tools/stream.hxx>
+
+struct LZWTableEntry {
+ USHORT nPrevCode;
+ USHORT nDataCount;
+ BYTE nData;
+};
+
+class LZWDecompressor {
+
+public:
+
+ LZWDecompressor();
+ ~LZWDecompressor();
+
+ void StartDecompression(SvStream & rIStream);
+
+ ULONG Decompress(BYTE * pTarget, ULONG nMaxCount);
+ // Liefert die Anzahl der geschriebenen Bytes, wenn < nMaxCount,
+ // sind keine weiteren Daten zu entpacken, oder es ist ein
+ // Fehler aufgetreten.
+
+private:
+
+ USHORT GetNextCode();
+ void AddToTable(USHORT nPrevCode, USHORT nCodeFirstData);
+ void DecompressSome();
+
+ SvStream * pIStream;
+
+ LZWTableEntry * pTable;
+ USHORT nTableSize;
+
+ BOOL bEOIFound, bInvert, bFirst;
+
+ USHORT nOldCode;
+
+ BYTE * pOutBuf;
+ BYTE * pOutBufData;
+ USHORT nOutBufDataLen;
+
+ BYTE nInputBitsBuf;
+ USHORT nInputBitsBufSize;
+};
+
+
+#endif
+
+
diff --git a/filter/source/graphicfilter/itiff/makefile.mk b/filter/source/graphicfilter/itiff/makefile.mk
new file mode 100644
index 000000000000..07fcf0ffdff4
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=filter
+TARGET=itiff
+DEPTARGET=vitiff
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein ----------------------------------------------------------
+
+.IF "$(editdebug)"!="" || "$(EDITDEBUG)"!=""
+CDEFS+= -DEDITDEBUG
+.ENDIF
+.IF "$(L10N_framework)"==""
+SLOFILES = $(SLO)$/itiff.obj \
+ $(SLO)$/lzwdecom.obj \
+ $(SLO)$/ccidecom.obj
+
+EXCEPTIONSNOOPTFILES= $(SLO)$/itiff.obj
+
+# ==========================================================================
+
+SHL1TARGET= iti$(DLLPOSTFIX)
+SHL1IMPLIB= itiff
+SHL1STDLIBS= $(VCLLIB) $(TOOLSLIB) $(SALLIB)
+SHL1LIBS= $(SLB)$/itiff.lib # $(LB)$/rtftoken.lib
+
+.IF "$(GUI)" != "UNX"
+.IF "$(COM)" != "GCC"
+SHL1OBJS= $(SLO)$/itiff.obj
+.ENDIF
+.ENDIF
+
+SHL1VERSIONMAP=exports.map
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME=$(SHL1TARGET)
+.ENDIF
+
+# ==========================================================================
+
+.INCLUDE : target.mk