diff --git a/sffview/tags/REL0_5_0/.cproject b/sffview/tags/REL0_5_0/.cproject
new file mode 100644
index 0000000..e87ea46
--- /dev/null
+++ b/sffview/tags/REL0_5_0/.cproject
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sffview/tags/REL0_5_0/.project b/sffview/tags/REL0_5_0/.project
new file mode 100644
index 0000000..e00ec5c
--- /dev/null
+++ b/sffview/tags/REL0_5_0/.project
@@ -0,0 +1,27 @@
+
+
+ sffview
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/sffview/tags/REL0_5_0/.settings/language.settings.xml b/sffview/tags/REL0_5_0/.settings/language.settings.xml
new file mode 100644
index 0000000..86102d7
--- /dev/null
+++ b/sffview/tags/REL0_5_0/.settings/language.settings.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/sffview/tags/REL0_5_0/.settings/org.eclipse.cdt.codan.core.prefs b/sffview/tags/REL0_5_0/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100644
index 0000000..3ab3be8
--- /dev/null
+++ b/sffview/tags/REL0_5_0/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,67 @@
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.checkers.noreturn=Error
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>true,empty_case_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
diff --git a/sffview/tags/REL0_5_0/Makefile b/sffview/tags/REL0_5_0/Makefile
new file mode 100644
index 0000000..6d4ed38
--- /dev/null
+++ b/sffview/tags/REL0_5_0/Makefile
@@ -0,0 +1,36 @@
+#
+# File: Makefile for samples
+# Author: Robert Roebling
+# Created: 1999
+# Updated:
+# Copyright: (c) 1998 Robert Roebling
+#
+# This makefile requires a Unix version of wxWindows
+# to be installed on your system. This is most often
+# done typing "make install" when using the complete
+# sources of wxWindows or by installing the two
+# RPM packages wxGTK.XXX.rpm and wxGTK-devel.XXX.rpm
+# under Linux.
+#
+
+CC = g++
+
+PROGRAM = sffview
+OBJECTS = $(PROGRAM).o common.o codes.o decoder.o sfffile.o sffapp.o sffdoc.o
+
+WXCONFIG_CPP = `wx-config --cflags`
+
+WXCONFIG_LD = `wx-config --libs`
+
+.SUFFIXES: .o .cpp
+
+.cpp.o :
+ $(CC) -g -Os -c $(WXCONFIG_CPP) -o $@ $<
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(OBJECTS)
+ $(CC) -o $(PROGRAM) $(OBJECTS) -Wl,--as-needed $(WXCONFIG_LD)
+
+clean:
+ rm -f *.o $(PROGRAM)
diff --git a/sffview/tags/REL0_5_0/bitmaps/actual_size.bmp b/sffview/tags/REL0_5_0/bitmaps/actual_size.bmp
new file mode 100644
index 0000000..982d107
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/actual_size.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/actual_size.xpm b/sffview/tags/REL0_5_0/bitmaps/actual_size.xpm
new file mode 100644
index 0000000..513f585
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/actual_size.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *actual_size_xpm[]={
+"16 15 3 1",
+"# c None",
+". c #000000",
+"a c #ffffff",
+"...........#####",
+".aaaaaaaaa..####",
+".aaaaaaaaa.a.###",
+".aaaaaaaaa....##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+".aaaaaaaaaaaa.##",
+"..............##"};
diff --git a/sffview/tags/REL0_5_0/bitmaps/fit_width.bmp b/sffview/tags/REL0_5_0/bitmaps/fit_width.bmp
new file mode 100644
index 0000000..6cd5f27
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/fit_width.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/fit_width.xpm b/sffview/tags/REL0_5_0/bitmaps/fit_width.xpm
new file mode 100644
index 0000000..8b292d3
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/fit_width.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *fit_width_xpm[]={
+"16 15 5 1",
+". c None",
+"a c None",
+"b c #000000",
+"# c #585858",
+"c c #ffffff",
+".##############a",
+".#............#a",
+".#..b......b..#a",
+".#.bbbbbbbbbb.#a",
+".#..b......b..#a",
+".#............#a",
+".#.bbbbbbb....#a",
+".#.bcccccbb...#a",
+".#.bcccccbcb..#a",
+".#.bcccccbbbb.#.",
+".#.bccccccccb.#.",
+".#.bccccccccb.#.",
+".#.bccccccccb.#.",
+".#.bccccccccb.#a",
+".##############a"};
diff --git a/sffview/tags/REL0_5_0/bitmaps/fit_window.bmp b/sffview/tags/REL0_5_0/bitmaps/fit_window.bmp
new file mode 100644
index 0000000..8693b16
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/fit_window.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/fit_window.xpm b/sffview/tags/REL0_5_0/bitmaps/fit_window.xpm
new file mode 100644
index 0000000..6943068
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/fit_window.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *fit_window_xpm[]={
+"16 15 5 1",
+". c None",
+"a c None",
+"b c #000000",
+"# c #585858",
+"c c #ffffff",
+".##############a",
+".#............#a",
+".#.bbbbbbb....#a",
+".#.bcccccbb...#a",
+".#.bcccccbcb..#a",
+".#.bcccccbbbb.#a",
+".#.bccccccccb.#a",
+".#.bccccccccb.#a",
+".#.bccccccccb.#a",
+".#.bccccccccb.#.",
+".#.bccccccccb.#.",
+".#.bccccccccb.#.",
+".#.bbbbbbbbbb.#.",
+".#............#a",
+".##############a"};
diff --git a/sffview/tags/REL0_5_0/bitmaps/flipx.bmp b/sffview/tags/REL0_5_0/bitmaps/flipx.bmp
new file mode 100644
index 0000000..81e6541
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/flipx.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/flipx.xpm b/sffview/tags/REL0_5_0/bitmaps/flipx.xpm
new file mode 100644
index 0000000..089ec99
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/flipx.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *flipx_xpm[]={
+"16 15 3 1",
+". c None",
+"# c #000000",
+"a c #000080",
+"................",
+".......#........",
+".....#.#.a......",
+".....#.#.a......",
+"....##...aa.....",
+"....##.#.aa.....",
+"....##...aa.....",
+"...###.#.aaa....",
+"...###.#.aaa....",
+"...###.#.aaa....",
+"..####...aaaa...",
+"..####.#.aaaa...",
+".......#........",
+".......#........",
+"................"};
diff --git a/sffview/tags/REL0_5_0/bitmaps/flipy.bmp b/sffview/tags/REL0_5_0/bitmaps/flipy.bmp
new file mode 100644
index 0000000..b89103c
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/flipy.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/flipy.xpm b/sffview/tags/REL0_5_0/bitmaps/flipy.xpm
new file mode 100644
index 0000000..73c57c2
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/flipy.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *flipy_xpm[]={
+"16 15 3 1",
+". c None",
+"# c #000000",
+"a c #000040",
+"................",
+"...........##...",
+".........####...",
+"......#######...",
+"....#########...",
+"..###########...",
+"................",
+".####.#####.###.",
+"................",
+"..aaaaaaaaaaa...",
+"....aaaaaaaaa...",
+"......aaaaaaa...",
+".........aaaa...",
+"...........aa...",
+"................"};
diff --git a/sffview/tags/REL0_5_0/bitmaps/help.bmp b/sffview/tags/REL0_5_0/bitmaps/help.bmp
new file mode 100644
index 0000000..2d9e692
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/help.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/help.xpm b/sffview/tags/REL0_5_0/bitmaps/help.xpm
new file mode 100644
index 0000000..1383265
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/help.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char *help_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 15 4 1",
+" c None",
+". c Black",
+"X c Blue",
+"o c #000080",
+/* pixels */
+" ",
+" ...... ",
+" .XXXXX.. ",
+" .XX...oX.. ",
+" .X.. .X.. ",
+" .X.. .XX.. ",
+" .. .XX.. ",
+" .XX.. ",
+" .X.. ",
+" .X.. ",
+" .o.. ",
+" .. ",
+" .XX.. ",
+" .XX.. ",
+" ... "
+};
diff --git a/sffview/tags/REL0_5_0/bitmaps/next.bmp b/sffview/tags/REL0_5_0/bitmaps/next.bmp
new file mode 100644
index 0000000..253f8f2
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/next.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/next.xpm b/sffview/tags/REL0_5_0/bitmaps/next.xpm
new file mode 100644
index 0000000..f9f00ca
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/next.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * next_xpm[] = {
+"16 16 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" ",
+" . ",
+" ... ",
+" ..... ",
+" ....... ",
+" ......... ",
+" ....... ",
+" ..... ",
+" ... ",
+" . ",
+" ",
+" ",
+" ",
+" "};
diff --git a/sffview/tags/REL0_5_0/bitmaps/open.bmp b/sffview/tags/REL0_5_0/bitmaps/open.bmp
new file mode 100644
index 0000000..bbf93fe
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/open.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/open.xpm b/sffview/tags/REL0_5_0/bitmaps/open.xpm
new file mode 100644
index 0000000..2a53d68
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/open.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char *open_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 15 5 1",
+" c None",
+". c Black",
+"X c Yellow",
+"o c Gray100",
+"O c #bfbf00",
+/* pixels */
+" ",
+" ... ",
+" . . .",
+" ..",
+" ... ...",
+" .XoX....... ",
+" .oXoXoXoXo. ",
+" .XoXoXoXoX. ",
+" .oXoX..........",
+" .XoX.OOOOOOOOO.",
+" .oo.OOOOOOOOO. ",
+" .X.OOOOOOOOO. ",
+" ..OOOOOOOOO. ",
+" ........... ",
+" "
+};
diff --git a/sffview/tags/REL0_5_0/bitmaps/prev.bmp b/sffview/tags/REL0_5_0/bitmaps/prev.bmp
new file mode 100644
index 0000000..14044f8
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/prev.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/prev.xpm b/sffview/tags/REL0_5_0/bitmaps/prev.xpm
new file mode 100644
index 0000000..6f96522
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/prev.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * prev_xpm[] = {
+"16 16 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" ",
+" . ",
+" ... ",
+" ..... ",
+" ....... ",
+" ......... ",
+" ....... ",
+" ..... ",
+" ... ",
+" . ",
+" ",
+" ",
+" ",
+" "};
diff --git a/sffview/tags/REL0_5_0/bitmaps/preview.bmp b/sffview/tags/REL0_5_0/bitmaps/preview.bmp
new file mode 100644
index 0000000..da1f4db
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/preview.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/preview.xpm b/sffview/tags/REL0_5_0/bitmaps/preview.xpm
new file mode 100644
index 0000000..78de7c4
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/preview.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char *paste_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 15 5 1",
+" c Black",
+". c None",
+"X c Gray100",
+"o c #808080",
+"O c Cyan",
+/* pixels */
+" .......",
+" XXXXXXX ......",
+" XXXXXXX . .....",
+" XXXXXXX ....",
+" XXXXXXXXXX ....",
+" XXXXXXX ....",
+" XXXXXX o..o ...",
+" XXXXX oOO.oo ..",
+" XXXXX .O..o. ..",
+" XXXXX ....o. ..",
+" XXXXX o..Ooo ..",
+" XXXXXX o..o o..",
+" XXXXXXX o .",
+" XXXXXXXXXX . ",
+" .. "
+};
diff --git a/sffview/tags/REL0_5_0/bitmaps/print.bmp b/sffview/tags/REL0_5_0/bitmaps/print.bmp
new file mode 100644
index 0000000..00319b5
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/print.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/print.xpm b/sffview/tags/REL0_5_0/bitmaps/print.xpm
new file mode 100644
index 0000000..bbac2d4
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/print.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char *print_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 15 5 1",
+" c None",
+". c Black",
+"X c Gray100",
+"o c #808000",
+"O c Yellow",
+/* pixels */
+" ",
+" ......... ",
+" .XXXXXXXX. ",
+" .X.....X. ",
+" .XXXXXXXX. ",
+" .X.....X.... ",
+" .XXXXXXXX. . .",
+" .......... . ..",
+". . . .",
+"............. .",
+". ooo . . ",
+". OOO ... ",
+"............. . ",
+" . . . ",
+" ........... "
+};
diff --git a/sffview/tags/REL0_5_0/bitmaps/zoomin.bmp b/sffview/tags/REL0_5_0/bitmaps/zoomin.bmp
new file mode 100644
index 0000000..af7521a
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/zoomin.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/zoomin.xpm b/sffview/tags/REL0_5_0/bitmaps/zoomin.xpm
new file mode 100644
index 0000000..b46447a
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/zoomin.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * zoomin_xpm[] = {
+"16 16 3 1",
+" c None",
+". c Black",
+"X c Gray100",
+" .... ",
+" ..XXXX.. ",
+" .XXXXXXXX. ",
+" .XXX..XXX. ",
+".XXXX..XXXX. ",
+".XX......XX. ",
+".XX......XX. ",
+".XXXX..XXXX. ",
+" .XXX..XXX. ",
+" .XXXXXXXX. ",
+" ..XXXX... ",
+" .... ... ",
+" ... ",
+" ... ",
+" ... ",
+" .. "
+};
diff --git a/sffview/tags/REL0_5_0/bitmaps/zoomout.bmp b/sffview/tags/REL0_5_0/bitmaps/zoomout.bmp
new file mode 100644
index 0000000..764ed9e
Binary files /dev/null and b/sffview/tags/REL0_5_0/bitmaps/zoomout.bmp differ
diff --git a/sffview/tags/REL0_5_0/bitmaps/zoomout.xpm b/sffview/tags/REL0_5_0/bitmaps/zoomout.xpm
new file mode 100644
index 0000000..6688363
--- /dev/null
+++ b/sffview/tags/REL0_5_0/bitmaps/zoomout.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * zoomout_xpm[] = {
+"16 16 3 1",
+" c None",
+". c Black",
+"X c Gray100",
+" .... ",
+" ..XXXX.. ",
+" .XXXXXXXX. ",
+" .XXXXXXXX. ",
+".XXXXXXXXXX. ",
+".XX......XX. ",
+".XX......XX. ",
+".XXXXXXXXXX. ",
+" .XXXXXXXX. ",
+" .XXXXXXXX. ",
+" ..XXXX... ",
+" .... ... ",
+" ... ",
+" ... ",
+" ... ",
+" .. "
+};
diff --git a/sffview/tags/REL0_5_0/codes.cpp b/sffview/tags/REL0_5_0/codes.cpp
new file mode 100644
index 0000000..2e0d68f
--- /dev/null
+++ b/sffview/tags/REL0_5_0/codes.cpp
@@ -0,0 +1,270 @@
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: codes.cpp,v 1.2 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include "sfftypes.h"
+#include "codes.h"
+
+#define EXT_CODES
+
+TABENTRY aMarkUpWhite[] = {
+ { 0x0080,RL_EOL, 8 },
+ { 0x0800,RL_EOL,12 },
+ { 0x001b, 64, 5 },
+ { 0x0009, 128, 5 },
+ { 0x003a, 192, 6 },
+ { 0x0076, 256, 7 },
+ { 0x006c, 320, 8 },
+ { 0x00ec, 384, 8 },
+ { 0x0026, 448, 8 },
+ { 0x00a6, 512, 8 },
+ { 0x0016, 576, 8 },
+ { 0x00e6, 640, 8 },
+ { 0x0066, 704, 9 },
+ { 0x0166, 768, 9 },
+ { 0x0096, 832, 9 },
+ { 0x0196, 896, 9 },
+ { 0x0056, 960, 9 },
+ { 0x0156, 1024, 9 },
+ { 0x00d6, 1088, 9 },
+ { 0x01d6, 1152, 9 },
+ { 0x0036, 1216, 9 },
+ { 0x0136, 1280, 9 },
+ { 0x00b6, 1344, 9 },
+ { 0x01b6, 1408, 9 },
+ { 0x0032, 1472, 9 },
+ { 0x0132, 1536, 9 },
+ { 0x00b2, 1600, 9 },
+ { 0x0006, 1664, 6 },
+ { 0x01b2, 1728, 9 },
+#ifdef EXT_CODES
+ { 0x0080, 1792, 11 },
+ { 0x0180, 1856, 11 },
+ { 0x0580, 1920, 11 },
+ { 0x0480, 1984, 12 },
+ { 0x0c80, 2048, 12 },
+ { 0x0280, 2112, 12 },
+ { 0x0a80, 2176, 12 },
+ { 0x0680, 2240, 12 },
+ { 0x0e80, 2304, 12 },
+ { 0x0380, 2368, 12 },
+ { 0x0b80, 2432, 12 },
+ { 0x0780, 2496, 12 },
+ { 0x0f80, 2560, 12 },
+#endif
+ { 0, 0, 0 }
+};
+TABENTRY aTermWhite[] = {
+ { 0x0080,RL_EOL, 8 },
+ { 0x0800,RL_EOL,12 },
+ { 0x00ac, 0, 8 },
+ { 0x0038, 1, 6 },
+ { 0x000e, 2, 4 },
+ { 0x0001, 3, 4 },
+ { 0x000d, 4, 4 },
+ { 0x0003, 5, 4 },
+ { 0x0007, 6, 4 },
+ { 0x000f, 7, 4 },
+ { 0x0019, 8, 5 },
+ { 0x0005, 9, 5 },
+ { 0x001c, 10, 5 },
+ { 0x0002, 11, 5 },
+ { 0x0004, 12, 6 },
+ { 0x0030, 13, 6 },
+ { 0x000b, 14, 6 },
+ { 0x002b, 15, 6 },
+ { 0x0015, 16, 6 },
+ { 0x0035, 17, 6 },
+ { 0x0072, 18, 7 },
+ { 0x0018, 19, 7 },
+ { 0x0008, 20, 7 },
+ { 0x0074, 21, 7 },
+ { 0x0060, 22, 7 },
+ { 0x0010, 23, 7 },
+ { 0x000a, 24, 7 },
+ { 0x006a, 25, 7 },
+ { 0x0064, 26, 7 },
+ { 0x0012, 27, 7 },
+ { 0x000c, 28, 7 },
+ { 0x0040, 29, 8 },
+ { 0x00c0, 30, 8 },
+ { 0x0058, 31, 8 },
+ { 0x00d8, 32, 8 },
+ { 0x0048, 33, 8 },
+ { 0x00c8, 34, 8 },
+ { 0x0028, 35, 8 },
+ { 0x00a8, 36, 8 },
+ { 0x0068, 37, 8 },
+ { 0x00e8, 38, 8 },
+ { 0x0014, 39, 8 },
+ { 0x0094, 40, 8 },
+ { 0x0054, 41, 8 },
+ { 0x00d4, 42, 8 },
+ { 0x0034, 43, 8 },
+ { 0x00b4, 44, 8 },
+ { 0x0020, 45, 8 },
+ { 0x00a0, 46, 8 },
+ { 0x0050, 47, 8 },
+ { 0x00d0, 48, 8 },
+ { 0x004a, 49, 8 },
+ { 0x00ca, 50, 8 },
+ { 0x002a, 51, 8 },
+ { 0x00aa, 52, 8 },
+ { 0x0024, 53, 8 },
+ { 0x00a4, 54, 8 },
+ { 0x001a, 55, 8 },
+ { 0x009a, 56, 8 },
+ { 0x005a, 57, 8 },
+ { 0x00da, 58, 8 },
+ { 0x0052, 59, 8 },
+ { 0x00d2, 60, 8 },
+ { 0x004c, 61, 8 },
+ { 0x00cc, 62, 8 },
+ { 0x002c, 63, 8 },
+ { 0, 0, 0 }
+};
+TABENTRY aMarkUpBlack[] = {
+ { 0x0080,RL_EOL, 8 },
+ { 0x0800,RL_EOL,12 },
+ { 0x03c0, 64, 10 },
+ { 0x0130, 128, 12 },
+ { 0x0930, 192, 12 },
+ { 0x0da0, 256, 12 },
+ { 0x0cc0, 320, 12 },
+ { 0x02c0, 384, 12 },
+ { 0x0ac0, 448, 12 },
+ { 0x06c0, 512, 13 },
+ { 0x16c0, 576, 13 },
+ { 0x0a40, 640, 13 },
+ { 0x1a40, 704, 13 },
+ { 0x0640, 768, 13 },
+ { 0x1640, 832, 13 },
+ { 0x09c0, 896, 13 },
+ { 0x19c0, 960, 13 },
+ { 0x05c0, 1024, 13 },
+ { 0x15c0, 1088, 13 },
+ { 0x0dc0, 1152, 13 },
+ { 0x1dc0, 1216, 13 },
+ { 0x0940, 1280, 13 },
+ { 0x1940, 1344, 13 },
+ { 0x0540, 1408, 13 },
+ { 0x1540, 1472, 13 },
+ { 0x0b40, 1536, 13 },
+ { 0x1b40, 1600, 13 },
+ { 0x04c0, 1664, 13 },
+ { 0x14c0, 1728, 13 },
+#ifdef EXT_CODES
+ { 0x0080, 1792, 11 },
+ { 0x0180, 1856, 11 },
+ { 0x0580, 1920, 11 },
+ { 0x0480, 1984, 12 },
+ { 0x0c80, 2048, 12 },
+ { 0x0280, 2112, 12 },
+ { 0x0a80, 2176, 12 },
+ { 0x0680, 2240, 12 },
+ { 0x0e80, 2304, 12 },
+ { 0x0380, 2368, 12 },
+ { 0x0b80, 2432, 12 },
+ { 0x0780, 2496, 12 },
+ { 0x0f80, 2560, 12 },
+#endif
+ { 0, 0, 0 }
+};
+TABENTRY aTermBlack[] = {
+ { 0x0080,RL_EOL, 8 },
+ { 0x0800,RL_EOL,12 },
+ { 0x03b0, 0, 10 },
+ { 0x0002, 1, 3 },
+ { 0x0003, 2, 2 },
+ { 0x0001, 3, 2 },
+ { 0x0006, 4, 3 },
+ { 0x000c, 5, 4 },
+ { 0x0004, 6, 4 },
+ { 0x0018, 7, 5 },
+ { 0x0028, 8, 6 },
+ { 0x0008, 9, 6 },
+ { 0x0010, 10, 7 },
+ { 0x0050, 11, 7 },
+ { 0x0070, 12, 7 },
+ { 0x0020, 13, 8 },
+ { 0x00e0, 14, 8 },
+ { 0x0030, 15, 9 },
+ { 0x03a0, 16, 10 },
+ { 0x0060, 17, 10 },
+ { 0x0040, 18, 10 },
+ { 0x0730, 19, 11 },
+ { 0x00b0, 20, 11 },
+ { 0x01b0, 21, 11 },
+ { 0x0760, 22, 11 },
+ { 0x00a0, 23, 11 },
+ { 0x0740, 24, 11 },
+ { 0x00c0, 25, 11 },
+ { 0x0530, 26, 12 },
+ { 0x0d30, 27, 12 },
+ { 0x0330, 28, 12 },
+ { 0x0b30, 29, 12 },
+ { 0x0160, 30, 12 },
+ { 0x0960, 31, 12 },
+ { 0x0560, 32, 12 },
+ { 0x0d60, 33, 12 },
+ { 0x04b0, 34, 12 },
+ { 0x0cb0, 35, 12 },
+ { 0x02b0, 36, 12 },
+ { 0x0ab0, 37, 12 },
+ { 0x06b0, 38, 12 },
+ { 0x0eb0, 39, 12 },
+ { 0x0360, 40, 12 },
+ { 0x0b60, 41, 12 },
+ { 0x05b0, 42, 12 },
+ { 0x0db0, 43, 12 },
+ { 0x02a0, 44, 12 },
+ { 0x0aa0, 45, 12 },
+ { 0x06a0, 46, 12 },
+ { 0x0ea0, 47, 12 },
+ { 0x0260, 48, 12 },
+ { 0x0a60, 49, 12 },
+ { 0x04a0, 50, 12 },
+ { 0x0ca0, 51, 12 },
+ { 0x0240, 52, 12 },
+ { 0x0ec0, 53, 12 },
+ { 0x01c0, 54, 12 },
+ { 0x0e40, 55, 12 },
+ { 0x0140, 56, 12 },
+ { 0x01a0, 57, 12 },
+ { 0x09a0, 58, 12 },
+ { 0x0d40, 59, 12 },
+ { 0x0340, 60, 12 },
+ { 0x05a0, 61, 12 },
+ { 0x0660, 62, 12 },
+ { 0x0e60, 63, 12 },
+ { 0, 0, 0 }
+};
diff --git a/sffview/tags/REL0_5_0/codes.h b/sffview/tags/REL0_5_0/codes.h
new file mode 100644
index 0000000..1e6cfb4
--- /dev/null
+++ b/sffview/tags/REL0_5_0/codes.h
@@ -0,0 +1,49 @@
+#ifndef __CODES_H__
+#define __CODES_H__
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: codes.h,v 1.2 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+typedef struct {
+ sff_word code; /* code, right justified, lsb-first, zero filled */
+ int run; /* runlength */
+ sff_byte bits; /* codewidth in bits */
+} TABENTRY, *LPTABENTRY;
+
+#define RL_EOL -2
+
+extern TABENTRY aMarkUpWhite[];
+extern TABENTRY aTermWhite[];
+extern TABENTRY aMarkUpBlack[];
+extern TABENTRY aTermBlack[];
+
+#endif // __CODES_H__
diff --git a/sffview/tags/REL0_5_0/common.cpp b/sffview/tags/REL0_5_0/common.cpp
new file mode 100644
index 0000000..47f1701
--- /dev/null
+++ b/sffview/tags/REL0_5_0/common.cpp
@@ -0,0 +1,200 @@
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: common.cpp,v 1.4 2009/04/28 19:07:10 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include "sfftypes.h"
+#include "common.h"
+#include "errno.h"
+
+#include
+#if defined(_MSC_VER)
+#include
+#else
+#include
+#endif
+#include
+#include
+
+#include
+#include
+#include
+
+using namespace std;
+
+#ifdef _MSC_VER
+#define fileno _fileno
+#endif
+
+//-----------------------------------------------------------------
+
+const std::string CSimpleException::m_aReasons[err_count+1] =
+{
+// err_invalidfile
+ "Not a valid sff file.",
+// err_corruptfile,
+ "File seems corrupt. Reading abandoned.",
+// err_lastpageread,
+ "Last page read.",
+// err_notsupported,
+ "Operation not supported.",
+// err_openfile,
+ "Can't open file.",
+// err_closedfile,
+ "Operation on closed file.",
+// err_findPath,
+ "Path not found.",
+// err_nowhitestart,
+ "Line doesn't begin with white code.",
+// err_noblackcode,
+ "White code not followed by black code.",
+// err_noblackterm,
+ "Black MUC not followed by black TERM.",
+// err_nowhiteterm,
+ "White MUC not followed by white TERM.",
+// err_invalidversion,
+ "OOps. Don't know how to handle this Fileversion.",
+// err_unknowncoding,
+ "Oh my dear. Don't know how to handle this encoding.",
+// err_toomuchformats,
+ "Please specify only one output format.",
+// err_cmdline,
+ "Error in commandline.",
+// err_noformat,
+ "No output format specified.",
+// err_outfileexists,
+ "Output file already exists, use -f to force overwrite.",
+// err_outfileisdir,
+ "Given output file is directory.",
+// err_outdir,
+ "Cannot create output directory.",
+//
+// ------------------- INSERT HERE
+//
+// err_count
+ "Unknown error."
+};
+
+const string& CSimpleException::what() const
+{
+ if (m_nError < err_count) {
+ return m_aReasons[m_nError];
+ }
+ return m_aReasons[err_count];
+}
+
+//-----------------------------------------------------------------
+
+CFile::CFile(const std::string& strPath) :
+ m_hFile(NULL)
+{
+ Open( strPath, "rb");
+}
+
+CFile::~CFile()
+{
+ Close();
+}
+
+void CFile::Open(const std::string& strPath, const char *pszMode)
+{
+ m_strPath = strPath;
+ if (( m_hFile ) || !( m_hFile = fopen(strPath.c_str(), pszMode)))
+ throw CSimpleException(CSimpleException::err_openfile);
+ m_nFileNo = fileno( m_hFile);
+}
+
+void CFile::Close()
+{
+ if (m_hFile) {
+ fclose(m_hFile);
+ }
+ m_hFile = NULL;
+}
+
+time_t CFile::GetModificationTime()
+{
+ struct stat buf;
+ if (::fstat( m_nFileNo, &buf ) == 0)
+ return buf.st_mtime ;
+ else
+ throw CSimpleException(CSimpleException::err_notsupported);
+}
+
+void CFile::SetModificationTime(const time_t &modtime)
+{
+ time_t ltime;
+ time( <ime);
+ utimbuf filetime;
+ filetime.actime = ltime;
+ filetime.modtime = modtime;
+ if (::utime( m_strPath.c_str(), &filetime) != 0) {
+ cerr << "CFile::SetModificationTime(): ErrorNr.: " << errno << endl;
+ }
+}
+
+sff_byte CFile::GetC()
+{
+ return ::fgetc(m_hFile);
+}
+
+void CFile::Read(void *pTarget, int nLen)
+{
+ size_t rc = ::fread(pTarget, 1, nLen, m_hFile);
+}
+
+void CFile::Write(void *pSource, int nLen)
+{
+ ::fwrite(pSource, nLen, 1, m_hFile);
+}
+
+sff_dword CFile::Tell()
+{
+ return ::ftell(m_hFile);
+}
+
+void CFile::Seek(int pos, CFile::seek_offset dir)
+{
+ int whence;
+ if (dir == sk_from_start) {
+ whence = SEEK_SET;
+ } else if (dir == sk_current) {
+ whence = SEEK_CUR;
+ } else {
+ return;
+ }
+ ::fseek(m_hFile, pos, whence);
+}
+
+bool CFile::Eof()
+{
+ return (feof(m_hFile) != 0);
+}
diff --git a/sffview/tags/REL0_5_0/common.h b/sffview/tags/REL0_5_0/common.h
new file mode 100644
index 0000000..a13687c
--- /dev/null
+++ b/sffview/tags/REL0_5_0/common.h
@@ -0,0 +1,114 @@
+#ifndef __COMMON_H__
+#define __COMMON_H__
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: common.h,v 1.2 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include
+
+class CSimpleException
+{
+public:
+ enum {
+ err_invalidfile = 0,
+ err_corruptfile,
+ err_lastpageread,
+ err_notsupported,
+ err_openfile,
+ err_closedfile,
+ err_findPath,
+ err_nowhitestart,
+ err_noblackcode,
+ err_noblackterm,
+ err_nowhiteterm,
+ err_invalidversion,
+ err_unknowncoding,
+ err_toomuchformats,
+ err_cmdline,
+ err_noformat,
+ err_outfileexists,
+ err_outfileisdir,
+ err_outdir,
+ // insert here
+ err_count
+ };
+
+ unsigned m_nError;
+
+ CSimpleException(const int nError) :
+ m_nError(nError) { };
+
+ const std::string& what() const;
+
+protected:
+ static const std::string m_aReasons[err_count+1];
+};
+
+//-----------------------------------------------------------------
+
+class CFile
+{
+protected:
+ FILE *m_hFile;
+ int m_nFileNo;
+ std::string m_strPath;
+
+public:
+ enum seek_offset {
+ sk_from_start,
+ sk_current
+ };
+
+ CFile() : m_hFile(NULL), m_nFileNo(0) { /* sonst nix */ };
+ CFile(const std::string& strPath);
+ // throw CSimpleException
+
+ virtual ~CFile();
+
+ FILE *GetFP() { return m_hFile; };
+ sff_byte GetC();
+ sff_dword Tell();
+ bool Eof();
+ void Seek(int pos, CFile::seek_offset dir);
+ void Read(void *pTarget, int nLen);
+ void Write(void *pSource, int nLen);
+
+ virtual void Open(const std::string& strPath, const char *pszMode);
+ // throw CSimpleException
+ virtual void Close();
+ // throw CSimpleException
+
+ time_t GetModificationTime();
+ virtual void SetModificationTime(const time_t &modtime);
+};
+
+#endif // __COMMON_H__
diff --git a/sffview/tags/REL0_5_0/decoder.cpp b/sffview/tags/REL0_5_0/decoder.cpp
new file mode 100644
index 0000000..23cf838
--- /dev/null
+++ b/sffview/tags/REL0_5_0/decoder.cpp
@@ -0,0 +1,293 @@
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: decoder.cpp,v 1.2 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include
+#include
+
+#include
+
+#include "sfftypes.h"
+#include "common.h"
+#include "codes.h"
+#include "decoder.h"
+
+using namespace std;
+
+//-Types-----------------------------------------------------------
+
+typedef enum {
+ NEED_WHITE,
+ NEED_BLACK,
+ NEED_WHITETERM,
+ NEED_BLACKTERM
+} TDecoderState;
+
+//-----------------------------------------------------------------
+
+void CBitSource::NeedBits(int nCount)
+{
+ while ((m_dwByteCount > 0) && (m_wBitsAvail < nCount)) {
+ m_dwAccu |= ((*m_pBuffer) << m_wBitsAvail);
+ m_wBitsAvail += 8;
+ --m_dwByteCount;
+ ++m_pBuffer;
+ }
+}
+
+void CBitSource::ClrBits(int nCount)
+{
+ m_wBitsAvail -= nCount;
+ m_dwAccu = (m_dwAccu >> nCount);
+}
+
+sff_word CBitSource::GetBits(int nCount)
+{
+ return (sff_word)(m_dwAccu & ((1<<(nCount))-1)); // untere x Bits ausmaskieren
+}
+
+bool CBitSource::NoMoreBits()
+{
+ return ((m_dwByteCount <= 0) && (m_dwAccu == 0));
+}
+
+CBitSource::CBitSource(void *pBuffer, sff_dword nByteCount) :
+ m_pBuffer((sff_byte *)pBuffer),
+ m_wBitsAvail(0),
+ m_dwAccu(0),
+ m_dwByteCount(nByteCount)
+{
+ /* sonst nix */
+}
+
+//-----------------------------------------------------------------
+
+void CBitSink::SetBits(int nCount)
+{
+ sff_byte *p;
+
+ p = m_pBuffer + (m_dwBitPos >> 3);
+#if defined(__WXMSW__) && (wxVERSION_NUMBER < 2600)
+ sff_byte mask = 0x80 >> (m_dwBitPos % 8);
+#else
+ sff_byte mask = 0x01 << (m_dwBitPos % 8);
+#endif
+ m_dwBitPos += nCount;
+ while (mask && nCount) {
+ *p |= mask;
+#if defined(__WXMSW__) && (wxVERSION_NUMBER < 2600)
+ mask >>= 1;
+#else
+ mask <<= 1;
+#endif
+ nCount--;
+ }
+ p++;
+ while (nCount >= 8) {
+ *p++ = 0xFF;
+ nCount -= 8;
+ }
+#if defined(__WXMSW__) && (wxVERSION_NUMBER < 2600)
+ mask = 0x80;
+#else
+ mask = 0x01;
+#endif
+ while (nCount) {
+ *p |= mask;
+#if defined(__WXMSW__) && (wxVERSION_NUMBER < 2600)
+ mask >>= 1;
+#else
+ mask <<= 1;
+#endif
+ nCount--;
+ }
+
+}
+
+void CBitSink::ClearBits(int nCount)
+{
+ m_dwBitPos += nCount;
+}
+
+CBitSink::CBitSink(void *pBuffer, sff_dword nByteCount) :
+m_pBuffer((sff_byte *)pBuffer),
+m_dwBitPos(0),
+m_dwByteCount(nByteCount),
+m_dwBitCount(nByteCount * 8)
+{
+}
+
+void CBitSink::Reset()
+{
+ m_dwBitPos = 0;
+}
+
+//-----------------------------------------------------------------
+
+void CByteSink::SetBits(int nCount)
+{
+ sff_byte *p;
+
+ p = m_pBuffer;
+ p += m_dwBitPos;
+ for (int i=0; icode) {
+ bits = GetBits(pTable->bits);
+ if (bits == pTable->code) {
+ ClrBits(pTable->bits);
+ return pTable->run;
+ }
+ pTable++;
+ }
+ return -1;
+}
+
+int CHuffDecoder::DecodeLine(IBitSink& aBitSink)
+{
+ int iRunlength;
+ m_dwRunlength = 0;
+ TDecoderState state = NEED_WHITE;
+
+ for (;;)
+ {
+ switch (state) {
+ case NEED_WHITE :
+ // we expect white_term or white_markup
+ NeedBits(12);
+ iRunlength = FindToken(aTermWhite);
+ if ( iRunlength == RL_EOL) {
+ goto exit; // EOL
+ }
+ if ( iRunlength >= 0 ) {
+ if ( iRunlength > 0 ) {
+ m_dwRunlength += iRunlength;
+ aBitSink.ClearBits(iRunlength);
+ }
+ state = NEED_BLACK;
+ } else {
+ iRunlength = FindToken(aMarkUpWhite);
+ if ( iRunlength == RL_EOL) {
+ goto exit; // EOL
+ }
+ if (iRunlength >= 0) {
+ if ( iRunlength > 0 ) {
+ m_dwRunlength += iRunlength;
+ aBitSink.ClearBits(iRunlength);
+ }
+ state = NEED_WHITETERM;
+ } else {
+ throw CSimpleException(CSimpleException::err_nowhitestart);
+ }
+ }
+ break;
+ case NEED_BLACK :
+ // we expect black_term or black_markup
+ NeedBits(13);
+ iRunlength = FindToken(aTermBlack);
+ if ( iRunlength == RL_EOL) {
+ goto exit; // EOL
+ }
+ if (iRunlength >= 0) {
+ if (iRunlength > 0 ) {
+ m_dwRunlength += iRunlength;
+ aBitSink.SetBits(iRunlength);
+ }
+ state = NEED_WHITE;
+ } else {
+ iRunlength = FindToken(aMarkUpBlack);
+ if (iRunlength == RL_EOL) {
+ goto exit; // EOL
+ }
+ if (iRunlength >= 0) {
+ if (iRunlength > 0) {
+ m_dwRunlength += iRunlength;
+ aBitSink.SetBits(iRunlength);
+ }
+ state = NEED_BLACKTERM;
+ } else {
+ state = NEED_WHITE;
+ // throw CSimpleException(CSimpleException::err_noblackcode);
+ // [PS] changed to allow further decoding...
+ // currently no problems known, but we'll see...
+ }
+ }
+ break;
+ case NEED_WHITETERM :
+ // expect White_Term only
+ NeedBits(8);
+ iRunlength = FindToken(aTermWhite);
+ if (iRunlength == RL_EOL) {
+ goto exit; // EOL
+ }
+ if (iRunlength >= 0) {
+ if ( iRunlength > 0 ) {
+ aBitSink.ClearBits(iRunlength);
+ m_dwRunlength += iRunlength;
+ }
+ state = NEED_BLACK;
+ } else {
+ throw CSimpleException(CSimpleException::err_nowhiteterm);
+ }
+ break;
+ case NEED_BLACKTERM :
+ // expect Black_Term only
+ NeedBits(12);
+ iRunlength = FindToken(aTermBlack);
+ if (iRunlength == RL_EOL) {
+ goto exit; // EOL
+ }
+ if (iRunlength >= 0) {
+ if ( iRunlength > 0 ) {
+ m_dwRunlength += iRunlength;
+ aBitSink.SetBits(iRunlength);
+ }
+ state = NEED_WHITE;
+ } else {
+ throw CSimpleException(CSimpleException::err_noblackterm);
+ }
+ break;
+ }
+ if (NoMoreBits())
+ break;
+ }
+exit:
+ return m_dwRunlength;
+}
diff --git a/sffview/tags/REL0_5_0/decoder.h b/sffview/tags/REL0_5_0/decoder.h
new file mode 100644
index 0000000..5030d57
--- /dev/null
+++ b/sffview/tags/REL0_5_0/decoder.h
@@ -0,0 +1,109 @@
+#ifndef __DECODER_H__
+#define __DECODER_H__
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: decoder.h,v 1.2 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+class CBitSource
+{
+private:
+ sff_byte *m_pBuffer;
+ sff_word m_wBitsAvail;
+ sff_dword m_dwAccu;
+ sff_dword m_dwByteCount;
+
+public:
+ void NeedBits(int nCount);
+ void ClrBits(int nCount);
+ sff_word GetBits(int nCount);
+ bool NoMoreBits();
+
+ CBitSource(void *pBuffer, sff_dword nByteCount);
+};
+
+//-----------------------------------------------------------------
+
+class IBitSink
+{
+public:
+ virtual void SetBits(int nCount) = 0;
+ virtual void ClearBits(int nCount) = 0;
+};
+
+//-----------------------------------------------------------------
+
+class CBitSink : public IBitSink
+{
+protected:
+ sff_byte *m_pBuffer;
+
+ sff_dword m_dwBitPos;
+ sff_dword m_dwByteCount;
+ sff_dword m_dwBitCount;
+
+public:
+ void Reset();
+
+ virtual void SetBits(int nCount);
+ virtual void ClearBits(int nCount);
+
+ CBitSink(void *pBuffer, sff_dword nByteCount);
+};
+
+//-----------------------------------------------------------------
+
+// writes ones
+class CByteSink : public CBitSink
+{
+public:
+ CByteSink(void *pBuffer, sff_dword nByteCount) :
+ CBitSink(pBuffer, nByteCount) { /* sonst nix */ };
+
+ void SetBits(int nCount);
+};
+
+//-----------------------------------------------------------------
+
+class CHuffDecoder : public CBitSource
+{
+protected:
+ sff_dword m_dwRunlength;
+
+public:
+ CHuffDecoder(sff_byte *pBuffer, sff_dword nByteCount) :
+ CBitSource(pBuffer, nByteCount) { /* sonst nix */ };
+
+ int FindToken(LPTABENTRY pTable);
+ int DecodeLine(IBitSink& aBitSink);
+};
+
+#endif // __DECODER_H__
diff --git a/sffview/tags/REL0_5_0/doc/changes b/sffview/tags/REL0_5_0/doc/changes
new file mode 100644
index 0000000..81261a7
--- /dev/null
+++ b/sffview/tags/REL0_5_0/doc/changes
@@ -0,0 +1,13 @@
+CHANGES
+-------
+
+V0.5 : me:
+ added print preview
+ update to wxWidgets 2.9.x
+
+V0.4 : me:
+ added printing support (BETA)
+ added MRU list
+ remember window position and size
+--
+$Id: changes,v 1.2 2006/10/29 19:33:57 pschaefer Exp $
diff --git a/sffview/tags/REL0_5_0/doc/copying b/sffview/tags/REL0_5_0/doc/copying
new file mode 100644
index 0000000..8226591
--- /dev/null
+++ b/sffview/tags/REL0_5_0/doc/copying
@@ -0,0 +1,20 @@
+This is sffview, a program to view structured fax files (sff).
+
+Copyright (c) 2000-2012 Peter Schaefer-Hutter ("THE AUTHOR")
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee.
+
+THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+You can contact the original author by email at peter.schaefer@gmx.de.
+
+$Id: copying,v 1.2 2006/10/29 16:42:27 pschaefer Exp $
diff --git a/sffview/tags/REL0_5_0/doc/readme b/sffview/tags/REL0_5_0/doc/readme
new file mode 100644
index 0000000..89a4820
--- /dev/null
+++ b/sffview/tags/REL0_5_0/doc/readme
@@ -0,0 +1,50 @@
+-----------
+SFFVIEW 0.4
+-----------
+
+Tool to view "structured fax files" in X11.
+
+SFF - Wotsit ?
+-----------------
+SFF means 'structured fax file' and is the file format that ISDN cards with
+CAPI interface expect and create.
+
+If you don't have an ISDN card: just don't care ;).
+
+Compilation
+-----------
+
+Windows:
+
+* First compile wxWidgets using static runtime and static wx libs:
+ cd \wx\build\msw:
+ nmake -f makefile.vc BUILD=debug UNICODE=1 SHARED=0 RUNTIME_LIBS=static
+ nmake -f makefile.vc BUILD=release UNICODE=1 SHARED=0 RUNTIME_LIBS=static
+
+* Then call
+ cd win32
+ nmake nodebug=1 /f makefile.vc all
+
+Linux:
+
+In most cases a call to 'make' may be sufficient.
+
+You need:
+
+wxGTK, version 2.9 or newer and all libraries that wxGTK needs itself.
+
+Contact:
+--------
+peter.schaefer@gmx.net
+http://sfftools.sourceforge.net
+
+Suggestions, extensions and patches welcome, flames will go to /dev/null.
+
+If you *really* like sffview or depend on it, please look into my wishlist:
+
+http://www.amazon.de/gp/registry/wishlist/OVQ6LSYS4E4D/028-1843567-9543743
+
+I'm always pleased to hear that somebody is actually using my software. If you
+can manage it, e-mail me a quick notice.
+
+Thanks!
diff --git a/sffview/tags/REL0_5_0/sffapp.cpp b/sffview/tags/REL0_5_0/sffapp.cpp
new file mode 100644
index 0000000..18cb94e
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sffapp.cpp
@@ -0,0 +1,476 @@
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: sffapp.cpp,v 1.4 2008/03/21 13:47:02 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include
+
+#if !wxUSE_DOC_VIEW_ARCHITECTURE
+#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
+#endif
+
+#include
+#include
+#include
+
+#include "sfftypes.h"
+#include "common.h"
+#include "codes.h"
+#include "decoder.h"
+#include "sffdoc.h"
+#include "sffview.h"
+#include "sffapp.h"
+
+#ifndef __WXMSW__
+#include "bitmaps/open.xpm"
+#include "bitmaps/help.xpm"
+#include "bitmaps/prev.xpm"
+#include "bitmaps/next.xpm"
+#include "bitmaps/zoomin.xpm"
+#include "bitmaps/zoomout.xpm"
+#include "bitmaps/flipx.xpm"
+#include "bitmaps/flipy.xpm"
+#include "bitmaps/fit_window.xpm"
+#include "bitmaps/fit_width.xpm"
+#include "bitmaps/actual_size.xpm"
+#endif
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// Commands that are always available
+
+#define ID_ABOUT 1
+
+// Commands that are available only if file loaded
+
+#define ID_ZOOMIN 10
+#define ID_ZOOMOUT 11
+#define ID_ZOOMNORMAL 12
+#define ID_ZOOMWIDTH 13
+#define ID_ZOOMHEIGHT 14
+#define ID_FLIPX 15
+#define ID_FLIPY 16
+
+#define ID_FILELOADED1 ID_ZOOMIN
+#define ID_FILELOADED2 ID_FLIPY
+
+// Commands that are available only if multipaged file loaded
+
+#define ID_PREVPAGE 20
+#define ID_NEXTPAGE 21
+
+#define ID_MULTIPAGE1 ID_PREVPAGE
+#define ID_MULTIPAGE2 ID_NEXTPAGE
+
+const int ID_TOOLBAR = 500;
+
+SffFrame *frame = (SffFrame *) NULL;
+
+IMPLEMENT_APP(SffApp)
+
+// ----------------------------------------------------------------------------
+// SffApp
+// ----------------------------------------------------------------------------
+
+SffApp::SffApp(void)
+{
+ m_docManager = (wxDocManager *) NULL;
+}
+
+bool SffApp::OnInit(void)
+{
+ SetAppName(wxT("SFF Viewer"));
+
+ //// Create a document manager
+ m_docManager = new wxDocManager();
+ m_config = new wxConfig(wxT("sffview"));
+
+ //// Create a template relating drawing documents to their views
+ (void) new wxDocTemplate(m_docManager, wxT("SFF File"), wxT("*.sff;*.SFF"),
+ wxT(""), wxT("sff"), wxT("SFF Doc"), wxT("SFF View"),
+ CLASSINFO(SffDocument), CLASSINFO(SffView));
+
+ m_docManager->SetMaxDocsOpen(2);
+
+ //// Create the main frame window
+ int x = m_config->Read(_T("/Window/x"), 1);
+ int y = m_config->Read(_T("/Window/y"), 1);
+ int w = m_config->Read(_T("/Window/w"), 750);
+ int h = m_config->Read(_T("/Window/h"), 600);
+
+ frame = new SffFrame(m_docManager, (wxFrame *) NULL, m_config, -1,
+ GetAppName(), wxPoint(x,y), wxSize(w,h),
+ wxDEFAULT_FRAME_STYLE);
+
+ //// Give it an icon (this is ignored in MDI mode: uses resources)
+#ifdef __WXMSW__
+ frame->SetIcon(wxIcon("sffview"));
+#endif
+
+ //// Make a menubar
+ wxMenu *file_menu = new wxMenu;
+
+ file_menu->Append(new wxMenuItem(file_menu, wxID_OPEN,
+ wxT("&Open..."), wxT("Opens a SFF fax file")));
+ file_menu->Append(new wxMenuItem(file_menu, wxID_CLOSE,
+ wxT("&Close"), wxT("Closes currently loaded file")));
+ file_menu->AppendSeparator();
+ file_menu->Append(new wxMenuItem(file_menu, wxID_PRINT,
+ wxT("&Print..."), wxT("Prints the currently loaded file")));
+ file_menu->Append(new wxMenuItem(file_menu, wxID_PRINT_SETUP,
+ wxT("Print &Setup..."), wxT("Let you choose a printer to print to")));
+ file_menu->Append(new wxMenuItem(file_menu, wxID_PREVIEW,
+ wxT("&Print Pre&view..."), wxT("Displays the file as it would be printed")));
+ file_menu->AppendSeparator();
+ file_menu->Append(new wxMenuItem(file_menu, wxID_EXIT,
+ wxT("E&xit"), wxT("Quits the application")));
+
+ // A nice touch: a history of files visited. Use this menu.
+ m_docManager->FileHistoryLoad(*m_config);
+ m_docManager->FileHistoryUseMenu(file_menu);
+ m_docManager->FileHistoryAddFilesToMenu();
+
+ wxMenu *view_menu = new wxMenu;
+ view_menu->Append(new wxMenuItem(view_menu, ID_PREVPAGE,
+ wxT("&Previous Page"), wxT("Displays the previous page of a multipage document")));
+ view_menu->Append(new wxMenuItem(view_menu, ID_NEXTPAGE,
+ wxT("&Next Page"), wxT("Displays the next page of a multipage document")));
+ view_menu->AppendSeparator();
+ view_menu->Append(new wxMenuItem(view_menu, ID_ZOOMNORMAL,
+ wxT("&Actual size"), wxT("Displays the page at normal scale")));
+ view_menu->Append(new wxMenuItem(view_menu, ID_ZOOMWIDTH,
+ wxT("Fit &width"), wxT("Fit page width in window")));
+ view_menu->Append(new wxMenuItem(view_menu, ID_ZOOMHEIGHT,
+ wxT("&Fit in window"), wxT("Fit whole page in window")));
+/*
+ view_menu->AppendSeparator();
+ view_menu->Append(new wxMenuItem(view_menu, ID_FLIPX,
+ "Flip &horizontal", "Mirrors the page horizontal"));
+ view_menu->Append(new wxMenuItem(view_menu, ID_FLIPY,
+ "Flip &vertical", "Mirrors the page vertical"));
+*/
+ wxMenu *help_menu = new wxMenu;
+ help_menu->Append(new wxMenuItem(view_menu, ID_ABOUT,
+ wxT("&About"), wxT("Shows information about the application")));
+
+ wxMenuBar *menu_bar = new wxMenuBar;
+ menu_bar->Append(file_menu, wxT("&File"));
+ menu_bar->Append(view_menu, wxT("&View"));
+ menu_bar->Append(help_menu, wxT("&Help"));
+
+ frame->canvas = frame->CreateCanvas((wxView *) NULL, frame);
+
+ //// Associate the menu bar with the frame
+ frame->SetMenuBar(menu_bar);
+ frame->RecreateToolbar();
+
+ frame->CreateStatusBar(2);
+ int widths[] = { -1, 100 };
+ frame->SetStatusWidths( 2, widths );
+ frame->Show(TRUE);
+
+ SetTopWindow(frame);
+
+ if (argc > 1) {
+ m_docManager->CreateDocument(argv[1], wxDOC_SILENT);
+ }
+
+ return TRUE;
+}
+
+int SffApp::OnExit(void)
+{
+ m_docManager->FileHistorySave(*m_config);
+ delete m_docManager;
+ delete m_config;
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+// SffFrame
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(SffFrame, wxDocParentFrame)
+BEGIN_EVENT_TABLE(SffFrame, wxDocParentFrame)
+ EVT_MENU(ID_ABOUT, SffFrame::OnAbout)
+ EVT_MENU(ID_PREVPAGE, SffFrame::OnPrevPage)
+ EVT_MENU(ID_NEXTPAGE, SffFrame::OnNextPage)
+// EVT_MENU(ID_ZOOMIN, SffFrame::OnZoomIn)
+// EVT_MENU(ID_ZOOMOUT, SffFrame::OnZoomOut)
+ EVT_MENU(ID_FLIPX, SffFrame::OnFlipX)
+ EVT_MENU(ID_FLIPY, SffFrame::OnFlipY)
+ EVT_MENU(ID_ZOOMNORMAL, SffFrame::OnZoomNormal)
+ EVT_MENU(ID_ZOOMWIDTH, SffFrame::OnFitWidth)
+ EVT_MENU(ID_ZOOMHEIGHT, SffFrame::OnFitHeight)
+ EVT_UPDATE_UI_RANGE(ID_FILELOADED1, ID_FILELOADED2, SffFrame::OnUpdateFileOps)
+ EVT_UPDATE_UI_RANGE(ID_MULTIPAGE1, ID_MULTIPAGE2, SffFrame::OnUpdateMultipage)
+ EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, SffFrame::OnMRUFile)
+ EVT_SIZE(SffFrame::OnSize)
+END_EVENT_TABLE()
+
+SffFrame::SffFrame(wxDocManager *manager, wxFrame *frame, wxConfig *config,
+ wxWindowID id, const wxString& title,
+ const wxPoint& pos, const wxSize& size, const long type) :
+ wxDocParentFrame(manager, frame, id, title, pos, size, type)
+{
+ canvas = (SffCanvas *) NULL;
+ m_config = config;
+}
+
+void SffFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+ (void)wxMessageBox(
+ wxT("This is SffView 0.5, a program to view structured fax files (sff)\n\n")
+ wxT("This software and its documentation is\n")
+ wxT("Copyright (C) 2000-2012 Peter Schaefer-Hutter\n\n")
+ wxT("Permission to use, copy, modify, and distribute this software and its ")
+ wxT("documentation for any purpose and without fee is hereby granted, provided ")
+ wxT("that the above copyright notice appear in all copies. This software ")
+ wxT("is provided 'as is' without expressed or implied warranty.\n\n")
+ wxT("You can contact the author by email at peter.schaefer@gmx.de"),
+ wxT("About..."), wxICON_INFORMATION | wxOK );
+}
+
+void SffFrame::RecreateToolbar()
+{
+ // delete and recreate the toolbar
+ wxToolBarBase *toolBar = GetToolBar();
+ delete toolBar;
+
+ SetToolBar(NULL);
+
+ long style = wxNO_BORDER | wxTB_FLAT | wxTB_DOCKABLE | wxTB_HORIZONTAL;
+
+ toolBar = CreateToolBar(style, ID_TOOLBAR);
+ toolBar->SetMargins( 4, 4 );
+
+ // Set up toolbar
+ wxBitmap toolBarBitmaps[11];
+
+ toolBarBitmaps[0] = wxBITMAP(open);
+ toolBarBitmaps[1] = wxBITMAP(prev);
+ toolBarBitmaps[2] = wxBITMAP(next);
+ toolBarBitmaps[3] = wxBITMAP(help);
+ toolBarBitmaps[4] = wxBITMAP(zoomin);
+ toolBarBitmaps[5] = wxBITMAP(zoomout);
+ toolBarBitmaps[6] = wxBITMAP(flipx);
+ toolBarBitmaps[7] = wxBITMAP(flipy);
+ toolBarBitmaps[8] = wxBITMAP(fit_window);
+ toolBarBitmaps[9] = wxBITMAP(fit_width);
+ toolBarBitmaps[10] = wxBITMAP(actual_size);
+
+#ifdef __WXMSW__
+ int width = 24;
+#else
+ int width = 16;
+#endif
+
+ int currentX = 5;
+
+ toolBar->AddTool(wxID_OPEN, wxEmptyString, toolBarBitmaps[0], wxT("Open File"));
+ currentX += width + 5;
+ toolBar->AddSeparator();
+ toolBar->AddTool(ID_PREVPAGE, wxEmptyString, toolBarBitmaps[1], wxT("Previous Page"));
+ currentX += width + 5;
+ toolBar->AddTool(ID_NEXTPAGE, wxEmptyString, toolBarBitmaps[2], wxT("Next Page"));
+ currentX += width + 5;
+ toolBar->AddSeparator();
+ toolBar->AddTool(ID_ZOOMNORMAL, wxEmptyString, toolBarBitmaps[10], wxT("Actual Size"));
+ currentX += width + 5;
+ toolBar->AddTool(ID_ZOOMWIDTH, wxEmptyString, toolBarBitmaps[9], wxT("Fit Width"));
+ currentX += width + 5;
+ toolBar->AddTool(ID_ZOOMHEIGHT, wxEmptyString, toolBarBitmaps[8], wxT("Fit In Window"));
+ currentX += width + 5;
+/*
+ toolBar->AddTool(ID_ZOOMIN, toolBarBitmaps[4], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Zoom +");
+ currentX += width + 5;
+ toolBar->AddTool(ID_ZOOMOUT, toolBarBitmaps[5], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Zoom -");
+ currentX += width + 5;
+ toolBar->AddTool(ID_FLIPX, toolBarBitmaps[6], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Horiz. spiegeln");
+ currentX += width + 5;
+ toolBar->AddTool(ID_FLIPY, toolBarBitmaps[7], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Vert. spiegeln");
+ currentX += width + 5;
+*/
+ toolBar->AddSeparator();
+ toolBar->AddTool(ID_ABOUT, wxEmptyString, toolBarBitmaps[3], wxT("Open About Dialog"));
+
+ toolBar->Realize();
+
+ toolBar->SetRows(1);
+}
+
+// Updates UI in respect to functions that are
+// only available if a file is loaded
+
+void SffFrame::OnUpdateFileOps(wxUpdateUIEvent& event)
+{
+ event.Enable(m_docManager->GetCurrentDocument() != NULL);
+}
+
+// Updates UI in respect to functions that are
+// only available if a multipaged file is loaded
+
+void SffFrame::OnUpdateMultipage(wxUpdateUIEvent& event)
+{
+ event.Enable(false);
+ SffDocument *pDoc = (SffDocument *)
+ m_docManager->GetCurrentDocument();
+ if ((pDoc != NULL) && (pDoc->GetPageCount() > 1)) {
+ if (event.GetId() == ID_PREVPAGE) {
+ event.Enable(pDoc->GetCurrentPageIdx() > 0);
+ } else if (event.GetId() == ID_NEXTPAGE) {
+ event.Enable(pDoc->GetCurrentPageIdx() < pDoc->GetPageCount()-1);
+ } else {
+ event.Enable(false);
+ }
+ return;
+ }
+ event.Enable(false);
+}
+
+// Creates a canvas. Called in OnInit as a child of the main window
+SffCanvas *SffFrame::CreateCanvas(wxView *view, wxFrame *parent)
+{
+ int width, height;
+ parent->GetClientSize(&width, &height);
+
+ // Non-retained canvas
+ SffCanvas *canvas = new SffCanvas(view, parent,
+ wxPoint(0, 0), wxSize(width, height));
+ //canvas->SetCursor(wxCursor(wxCURSOR_HAND));
+
+ // Give it scrollbars
+ // canvas->SetScrollbars(10, 10, 50, 50);
+// canvas->Clear();
+
+ return canvas;
+}
+
+void SffFrame::OnNextPage(wxCommandEvent& WXUNUSED(event))
+{
+ SffDocument *pDoc = (SffDocument *)
+ m_docManager->GetCurrentDocument();
+ if ((pDoc != NULL) && (pDoc->GetPageCount() > 1)) {
+ pDoc->NextPage();
+ }
+}
+
+void SffFrame::OnPrevPage(wxCommandEvent& WXUNUSED(event))
+{
+ SffDocument *pDoc = (SffDocument *)
+ m_docManager->GetCurrentDocument();
+ if ((pDoc != NULL) && (pDoc->GetPageCount() > 1)) {
+ pDoc->PrevPage();
+ }
+}
+
+void SffFrame::OnFlipX(wxCommandEvent& WXUNUSED(event))
+{
+ SffView *pView = (SffView *)
+ m_docManager->GetCurrentView();
+ if (pView != NULL) {
+ pView->FlipX();
+ }
+}
+
+void SffFrame::OnFlipY(wxCommandEvent& WXUNUSED(event))
+{
+ SffView *pView = (SffView *)
+ m_docManager->GetCurrentView();
+ if (pView != NULL) {
+ pView->FlipY();
+ }
+}
+
+void SffFrame::OnFitWidth(wxCommandEvent& WXUNUSED(event))
+{
+ SffView *pView = (SffView *)
+ m_docManager->GetCurrentView();
+ if (pView != NULL) {
+ pView->SetScale(SffView::FITWIDTH);
+ }
+}
+
+void SffFrame::OnFitHeight(wxCommandEvent& WXUNUSED(event))
+{
+ SffView *pView = (SffView *)
+ m_docManager->GetCurrentView();
+ if (pView != NULL) {
+ pView->SetScale(SffView::FULLPAGE);
+ }
+}
+
+void SffFrame::OnZoomNormal(wxCommandEvent& WXUNUSED(event))
+{
+ SffView *pView = (SffView *)
+ m_docManager->GetCurrentView();
+ if (pView != NULL) {
+ pView->SetScale(SffView::FULLSCALE);
+ }
+}
+
+void SffFrame::OnSize(wxSizeEvent& event)
+{
+ wxFrame::OnSize(event);
+
+ SffView *pView = (SffView *)
+ m_docManager->GetCurrentView();
+ if (pView != NULL) {
+ pView->CalcScale();
+ }
+}
+
+void SffFrame::OnMRUFile(wxCommandEvent& event)
+{
+ wxString f(m_docManager->GetHistoryFile(event.GetId() - wxID_FILE1));
+ if (!f.IsEmpty())
+ (void)m_docManager->CreateDocument(f, wxDOC_SILENT);
+}
+
+bool SffFrame::Destroy()
+{
+ int x, y, w, h;
+ GetPosition(&x, &y); GetSize(&w, &h);
+ m_config->Write(_T("/Window/x"), (long)x);
+ m_config->Write(_T("/Window/y"), (long)y);
+ m_config->Write(_T("/Window/w"), (long)w);
+ m_config->Write(_T("/Window/h"), (long)h);
+ return wxDocParentFrame::Destroy();
+}
+
+// ---------------------------------------------------
+
+SffFrame *GetMainFrame(void)
+{
+ return frame;
+}
diff --git a/sffview/tags/REL0_5_0/sffapp.h b/sffview/tags/REL0_5_0/sffapp.h
new file mode 100644
index 0000000..d258539
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sffapp.h
@@ -0,0 +1,107 @@
+#ifndef __SFFAPP_H__
+#define __SFFAPP_H__
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+$Id: sffapp.h,v 1.4 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+// ----------------------------------------------------------------------------
+// Class declarations
+// ----------------------------------------------------------------------------
+
+// forwards
+
+class wxDocManager;
+class wxConfig;
+class SffCanvas;
+
+// Main application class
+
+class SffApp : public wxApp
+{
+public:
+ SffApp(void);
+
+ bool OnInit(void);
+ int OnExit(void);
+
+protected:
+ wxDocManager* m_docManager;
+ wxConfig * m_config;
+};
+
+DECLARE_APP(SffApp)
+
+// Main frame class
+
+class SffFrame : public wxDocParentFrame
+{
+ DECLARE_CLASS(SffFrame)
+
+public:
+ SffCanvas *canvas;
+
+ SffFrame(wxDocManager *manager, wxFrame *frame,
+ wxConfig *config,
+ wxWindowID id, const wxString& title,
+ const wxPoint& pos, const wxSize& size,
+ const long type);
+
+ SffCanvas *CreateCanvas(wxView *view, wxFrame *parent);
+
+ void RecreateToolbar();
+ void OnUpdateFileOps(wxUpdateUIEvent& event);
+ void OnUpdateMultipage(wxUpdateUIEvent& event);
+
+ void OnAbout(wxCommandEvent& event);
+ void OnNextPage(wxCommandEvent& event);
+ void OnPrevPage(wxCommandEvent& event);
+
+ void OnFlipX(wxCommandEvent& event);
+ void OnFlipY(wxCommandEvent& event);
+
+ void OnZoomNormal(wxCommandEvent& event);
+ void OnFitWidth(wxCommandEvent& event);
+ void OnFitHeight(wxCommandEvent& event);
+
+ void OnMRUFile(wxCommandEvent& event);
+ void OnSize(wxSizeEvent& event);
+ bool Destroy();
+
+ DECLARE_EVENT_TABLE()
+
+protected:
+ wxConfig *m_config;
+};
+
+extern SffFrame *GetMainFrame(void);
+
+#endif // __SFFAPP_H__
diff --git a/sffview/tags/REL0_5_0/sffdoc.cpp b/sffview/tags/REL0_5_0/sffdoc.cpp
new file mode 100644
index 0000000..bd82d86
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sffdoc.cpp
@@ -0,0 +1,418 @@
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: sffdoc.cpp,v 1.4 2011/10/18 19:39:38 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include
+
+#if !wxUSE_DOC_VIEW_ARCHITECTURE
+#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
+#endif
+
+#include "sfftypes.h"
+#include "common.h"
+#include "codes.h"
+#include "decoder.h"
+#include "sfffile.h"
+#include "sffdoc.h"
+#include "sffview.h"
+
+#include
+using namespace std;
+
+// ---------------------------------------------------------------------
+
+CBitmapDecoder::CBitmapDecoder(wxUint32 aWidth, wxUint32 aHeight) :
+ m_pBitmap(0),
+ m_Width(aWidth),
+ m_Height(aHeight),
+ m_Scanline(0),
+ m_sink(m_abBuffer, sizeof(m_abBuffer))
+{
+ m_WidthInBytes = aWidth>>3;
+ m_Width = aWidth;
+ m_Height = aHeight;
+ m_pBitmap = new wxUint8[m_WidthInBytes*aHeight];
+ memset(m_pBitmap, 0x00, m_WidthInBytes*aHeight);
+ Reset();
+}
+
+CBitmapDecoder::~CBitmapDecoder()
+{
+ if (m_pBitmap) delete m_pBitmap;
+}
+
+void CBitmapDecoder::Reset()
+{
+ m_Scanline = 0;
+ m_sink.Reset();
+}
+
+void CBitmapDecoder::BlankLine()
+{
+ ::memset(m_abBuffer, 0x00, sizeof(m_abBuffer));
+}
+
+CBitSink& CBitmapDecoder::GetBitSink()
+{
+ m_sink.Reset();
+ return m_sink;
+}
+
+void CBitmapDecoder::WriteLine()
+{
+ if (m_Scanline < m_Height) {
+ memcpy(m_pBitmap+(m_WidthInBytes*m_Scanline), m_abBuffer, m_WidthInBytes);
+ ++m_Scanline;
+ }
+}
+
+const wxUint8 *CBitmapDecoder::GetBitmap()
+{
+ return m_pBitmap;
+}
+
+// ---------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(SffDocument, wxDocument)
+
+SffDocument::SffDocument(void) :
+ m_pSffFile(NULL),
+ m_pDecoder(NULL),
+ m_pPageBmp(NULL),
+ m_nPageIdx(0)
+{
+}
+
+SffDocument::~SffDocument(void)
+{
+ if (m_pSffFile) {
+ delete m_pSffFile;
+ }
+ if (m_pPageBmp) {
+ delete m_pPageBmp;
+ }
+ if (m_pDecoder) {
+ delete m_pDecoder;
+ }
+}
+
+bool SffDocument::OnOpenDocument(const wxString& filename)
+{
+ bool rc = false;
+
+ try {
+ wxBusyCursor wait;
+ m_nPageIdx = 0;
+ std::string strFN(filename.ToStdString());
+ m_pSffFile = new CSffFile(strFN);
+ m_pDecoder = new CBitmapDecoder(GetWidth(), GetHeight());
+ SetFilename(filename, TRUE);
+ Modify(FALSE);
+ CreatePageBitmap();
+ rc = true;
+ }
+ catch (const CSimpleException& e) {
+ wxLogError( (wxChar *) e.what().c_str() );
+ }
+ return rc;
+}
+
+int SffDocument::GetPageCount()
+{
+ wxASSERT(m_pSffFile != NULL);
+ return (m_pSffFile != NULL) ? m_pSffFile->GetPageCount() : 0;
+}
+
+int SffDocument::GetCurrentPageIdx()
+{
+ wxASSERT(m_pSffFile != NULL);
+ return m_nPageIdx;
+}
+
+void SffDocument::CreatePageBitmap()
+{
+ int i;
+ int lines, cols;
+ bool bLowRes;
+
+ if (m_pSffFile == NULL)
+ return;
+
+ try
+ {
+ TSFFRecord rec;
+ // CDCFile outfile;
+ m_pSffFile->SeekPage(m_nPageIdx);
+ bLowRes = m_pSffFile->IsLowRes(m_nPageIdx);
+ lines = GetHeight();
+ cols = GetWidth();
+ // Decode SFF Records ...
+ m_pDecoder->Reset();
+ while ((lines > 0) && m_pSffFile->GetRecord(rec)) {
+ switch(rec.type) {
+ case NORMAL :
+ m_pDecoder->BlankLine();
+ m_pSffFile->DecodeRecord(rec, m_pDecoder->GetBitSink());
+ m_pDecoder->WriteLine(); --lines;
+ if (bLowRes) { // double line if low-res
+ m_pDecoder->WriteLine(); --lines;
+ }
+ if (rec.pData != 0) free(rec.pData);
+ break;
+ case USERINFO :
+ // not supported
+ if (rec.pData != 0) free(rec.pData);
+ break;
+ case BADLINE :
+ case WHITESKIP :
+ // a white skip is, ah, skipped ;)
+ m_pDecoder->BlankLine();
+ for (i=0; i < rec.cb; ++i) {
+ m_pDecoder->WriteLine(); --lines;
+ if (bLowRes) { // double line if low-res
+ m_pDecoder->WriteLine(); --lines;
+ }
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ wxBitmap *pOld = m_pPageBmp;
+ m_pPageBmp = new wxBitmap((const char*)m_pDecoder->GetBitmap(),
+ GetWidth(), GetHeight());
+ UpdateAllViews();
+ if (pOld) {
+ delete pOld;
+ }
+ }
+ catch (CSimpleException e) {
+ wxLogError( (wxChar *)e.what().c_str() );
+ }
+}
+
+wxBitmap *SffDocument::GetPageBitmap(int nPage)
+{
+ int i;
+ int lines, cols;
+ bool bLowRes;
+
+
+ if (m_pSffFile == NULL)
+ return NULL;
+
+ wxBitmap *pBmp = NULL;
+
+ try
+ {
+ TSFFRecord rec;
+ // CDCFile outfile;
+ m_pSffFile->SeekPage(nPage-1);
+ bLowRes = m_pSffFile->IsLowRes(nPage-1);
+ lines = GetHeight();
+ cols = GetWidth();
+ // Decode SFF Records ...
+ m_pDecoder->Reset();
+ while ((lines > 0) && m_pSffFile->GetRecord(rec)) {
+ switch(rec.type) {
+ case NORMAL :
+ m_pDecoder->BlankLine();
+ m_pSffFile->DecodeRecord(rec, m_pDecoder->GetBitSink());
+ m_pDecoder->WriteLine(); --lines;
+ if (bLowRes) { // double line if low-res
+ m_pDecoder->WriteLine(); --lines;
+ }
+ if (rec.pData != 0) free(rec.pData);
+ break;
+ case USERINFO :
+ // not supported
+ if (rec.pData != 0) free(rec.pData);
+ break;
+ case BADLINE :
+ case WHITESKIP :
+ // a white skip is, ah, skipped ;)
+ m_pDecoder->BlankLine();
+ for (i=0; i < rec.cb; ++i) {
+ m_pDecoder->WriteLine(); --lines;
+ if (bLowRes) { // double line if low-res
+ m_pDecoder->WriteLine(); --lines;
+ }
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ pBmp = new wxBitmap((const char*)m_pDecoder->GetBitmap(),
+ GetWidth(), GetHeight());
+ }
+ catch (CSimpleException e) {
+ wxLogError( (wxChar *)e.what().c_str() );
+ }
+
+ return pBmp;
+}
+
+wxUint32 SffDocument::GetHeight()
+{
+ wxASSERT(m_pSffFile != NULL);
+ if (m_pSffFile != NULL) {
+ wxUint32 h = m_pSffFile->GetPageHeight(m_nPageIdx);
+ return m_pSffFile->IsLowRes(m_nPageIdx) ? h * 2 : h;
+ }
+ return 0;
+}
+
+wxUint32 SffDocument::GetWidth()
+{
+ wxASSERT(m_pSffFile != NULL);
+ if (m_pSffFile != NULL) {
+ return m_pSffFile->GetPageWidth(m_nPageIdx);
+ }
+ return 0;
+}
+
+void SffDocument::NextPage()
+{
+ wxASSERT(m_pSffFile != NULL);
+ if (m_pSffFile != NULL) {
+ if (m_nPageIdx < m_pSffFile->GetPageCount()) {
+ ++m_nPageIdx;
+ CreatePageBitmap();
+ }
+ }
+}
+
+void SffDocument::PrevPage()
+{
+ wxASSERT(m_pSffFile != NULL);
+ if (m_nPageIdx >= 1) {
+ --m_nPageIdx;
+ CreatePageBitmap();
+ }
+}
+/*
+void SffDocument::PreparePage(int nPage)
+{
+ wxASSERT(m_pSffFile != NULL);
+ if (m_nPageIdx >= 1) {
+ --m_nPageIdx;
+ CreatePageBitmap();
+ }
+}
+*/
+// ---------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(SffPrintout, wxPrintout)
+
+SffPrintout::SffPrintout(SffDocument *doc) :
+ wxPrintout()
+{
+ m_Doc = doc;
+ m_nPageCount = doc->GetPageCount();
+};
+
+bool SffPrintout::OnPrintPage(int page)
+{
+ wxBitmap *pBmp = m_Doc->GetPageBitmap(page);
+ int nBitmapHeight = pBmp->GetHeight();
+ int nBitmapWidth = pBmp->GetWidth();
+
+ wxDC *dc = GetDC();
+
+ wxMemoryDC mem_dc;
+ mem_dc.SelectObject(*pBmp);
+
+ // Get the logical pixels per inch of screen and printer
+ int ppiScreenX, ppiScreenY;
+ GetPPIScreen(&ppiScreenX, &ppiScreenY);
+ wxUnusedVar(ppiScreenY);
+ int ppiPrinterX, ppiPrinterY;
+ GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
+ wxUnusedVar(ppiPrinterY);
+
+ // This scales the DC so that the printout roughly represents the
+ // the screen scaling. The text point size _should_ be the right size
+ // but in fact is too small for some reason. This is a detail that will
+ // need to be addressed at some point but can be fudged for the
+ // moment.
+ float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
+
+ // Now we have to check in case our real page size is reduced
+ // (e.g. because we're drawing to a print preview memory DC)
+ int pageWidth, pageHeight;
+ int w, h;
+ dc->GetSize(&w, &h);
+ GetPageSizePixels(&pageWidth, &pageHeight);
+ wxUnusedVar(pageHeight);
+
+ // If printer pageWidth == current DC width, then this doesn't
+ // change. But we might be the preview bitmap width, so scale down.
+ float overallScale = scale * (float)(w/(float)pageWidth);
+ float zoomW = w; zoomW = zoomW/(nBitmapWidth*overallScale);
+ float zoomH = h; zoomH = zoomH/(nBitmapHeight*overallScale);
+ dc->SetUserScale(overallScale * zoomW, overallScale * zoomH);
+ dc->SetBackground(*wxWHITE_BRUSH);
+#if defined(__WXGTK__) && !wxCHECK_VERSION(2,8,0)
+ if (pageWidth != w) {
+ // Strange misbehaviour of older wxGTK -> if we blit zoomed, the colours
+ // get inversed ??!? Workaround: wxSRC_INVERT
+ dc->Blit(0,0,nBitmapWidth,nBitmapHeight,&mem_dc,0,0,wxSRC_INVERT);
+ } else {
+ dc->Blit(0,0,nBitmapWidth,nBitmapHeight,&mem_dc,0,0,wxCOPY);
+ }
+#else
+ dc->Blit(0,0,nBitmapWidth,nBitmapHeight,&mem_dc,0,0,wxCOPY);
+#endif
+ return TRUE;
+}
+
+bool SffPrintout::HasPage(int pageNum)
+{
+ return (pageNum <= m_nPageCount);
+}
+
+bool SffPrintout::OnBeginDocument(int startPage, int endPage)
+{
+ if (!wxPrintout::OnBeginDocument(startPage, endPage))
+ return FALSE;
+
+ return TRUE;
+}
+
+void SffPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
+{
+ *minPage = 1;
+ *maxPage = m_nPageCount;
+ *selPageFrom = 1;
+ *selPageTo = 1;
+}
diff --git a/sffview/tags/REL0_5_0/sffdoc.h b/sffview/tags/REL0_5_0/sffdoc.h
new file mode 100644
index 0000000..f2b9850
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sffdoc.h
@@ -0,0 +1,117 @@
+#ifndef __SFFDOC_H__
+#define __SFFDOC_H__
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+$Id: sffdoc.h,v 1.3 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include "wx/docview.h"
+
+class CSffFile;
+
+class CBitmapDecoder
+{
+protected:
+ CBitSink m_sink;
+ wxUint8 m_abBuffer[5120];
+ wxUint8 *m_pBitmap;
+ wxUint32 m_Width;
+ wxUint32 m_WidthInBytes;
+ wxUint32 m_Height;
+ wxUint32 m_Scanline;
+
+public:
+ CBitmapDecoder(wxUint32 aWidth, wxUint32 aHeight);
+ ~CBitmapDecoder();
+
+ void Reset();
+
+ void WriteLine();
+ void BlankLine();
+
+ CBitSink& GetBitSink();
+ const wxUint8 *GetBitmap();
+};
+
+class SffDocument: public wxDocument
+{
+ DECLARE_DYNAMIC_CLASS(SffDocument)
+
+protected:
+ CSffFile *m_pSffFile;
+ CBitmapDecoder *m_pDecoder;
+
+ wxBitmap *m_pPageBmp;
+ int m_nPageIdx;
+
+ void CreatePageBitmap();
+
+public:
+ SffDocument(void);
+ ~SffDocument(void);
+
+ int GetPageCount();
+ int GetCurrentPageIdx();
+
+ void NextPage();
+ void PrevPage();
+
+ wxUint32 GetHeight();
+ wxUint32 GetWidth();
+
+ wxBitmap *GetPageBitmap() { return m_pPageBmp; };
+ wxBitmap *GetPageBitmap(int nPage);
+
+ virtual bool OnOpenDocument(const wxString& filename);
+};
+
+class SffView;
+
+class SffPrintout : public wxPrintout
+{
+protected:
+ SffDocument *m_Doc;
+ int m_nPageCount;
+
+public:
+ SffPrintout(SffDocument *doc = NULL);
+
+ bool OnPrintPage(int page);
+ bool HasPage(int page);
+ bool OnBeginDocument(int startPage, int endPage);
+ void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo);
+
+private:
+ DECLARE_DYNAMIC_CLASS(SffPrintout)
+ DECLARE_NO_COPY_CLASS(SffPrintout)
+};
+
+#endif // __SFFDOC_H__
diff --git a/sffview/tags/REL0_5_0/sfffile.cpp b/sffview/tags/REL0_5_0/sfffile.cpp
new file mode 100644
index 0000000..721914a
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sfffile.cpp
@@ -0,0 +1,327 @@
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: sfffile.cpp,v 1.4 2008/06/29 09:30:48 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include
+#include
+#include
+#include
+
+#include "sfftypes.h"
+#include "common.h"
+#include "codes.h"
+#include "decoder.h"
+#include "sfffile.h"
+
+using namespace std;
+
+//-Constants-------------------------------------------------------
+
+sff_byte CSffFile::m_SFFID[4] = { 0x53, 0x66, 0x66, 0x66 };
+
+//-Types-----------------------------------------------------------
+
+typedef enum {
+ NEED_MAGIC,
+ NEED_PAGESTART,
+ NEED_PAGEHEADER,
+ NEED_RECORD,
+ LAST_PAGE
+} TScannerState;
+
+//-----------------------------------------------------------------
+
+CSffFile::CSffFile(const std::string& strFileName) :
+ CFile(strFileName)
+{
+ ScanFile();
+}
+
+CSffFile::~CSffFile()
+{
+ PAGEVECTOR::iterator it = m_acPages.begin();
+ for (; it != m_acPages.end(); it++) {
+ delete (*it);
+ }
+}
+
+void CSffFile::ScanFile()
+{
+ TSFFFileHeader dh;
+ TSFFPageHeader ph;
+ sff_byte b1 = 0, b2 = 0;
+ sff_word w;
+ int nLineCount = 0;
+ int fuzz = 0;
+ TSFFPage *pPage;
+
+ if (Eof())
+ return;
+
+ TScannerState state = NEED_MAGIC;
+ do {
+ switch (state) {
+ case NEED_MAGIC :
+ for (fuzz = 0; fuzz < 2048; ++fuzz) {
+ Seek(fuzz, CFile::sk_from_start);
+ Read(&dh, sizeof(dh));
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_invalidfile);
+ if (::memcmp(&dh.sff_id, &m_SFFID, sizeof(m_SFFID)) == 0)
+ break;
+ }
+ if (::memcmp(&dh.sff_id, &m_SFFID, sizeof(m_SFFID)) != 0)
+ throw CSimpleException(CSimpleException::err_invalidfile);
+ if (dh.version > 1)
+ throw CSimpleException(CSimpleException::err_invalidversion);
+ if (fuzz>0) {
+ dh.first_page += fuzz;
+ }
+ Seek(dh.first_page, CFile::sk_from_start);
+ state = NEED_PAGESTART;
+ break;
+ case NEED_PAGESTART :
+ b1 = GetC(); // Recordheader (0xFE fuer Seitenanfang)
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ if (b1 != 0xFE)
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ b1 = GetC(); // Recordlaenge (normalerweise 0x10)
+ if (b1 == 0)
+ state = LAST_PAGE;
+ else
+ state = NEED_PAGEHEADER;
+ break;
+ case NEED_PAGEHEADER :
+ Read(&ph, sizeof(TSFFPageHeader));
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ if (ph.coding > 0)
+ throw CSimpleException(CSimpleException::err_unknowncoding);
+ Seek(b1 - sizeof(TSFFPageHeader), CFile::sk_current); // skip user data
+ pPage = new TSFFPage;
+ pPage->filepos = Tell();
+ pPage->width = ph.linelen;
+ pPage->height = ph.pagelen;
+ // Values 254/255 are known for RVS COM
+ pPage->dpi = (ph.horiz_res == 0) ? 203 :
+ (ph.horiz_res == 255) ? 300 :
+ (ph.horiz_res == 254) ? 400 : 0;
+ pPage->lpi = (ph.vert_res == 0) ? 98 :
+ (ph.vert_res == 1) ? 196 :
+ (ph.vert_res == 255) ? 300 :
+ (ph.vert_res == 254) ? 400 : 0;
+ m_acPages.push_back(pPage);
+ state = NEED_RECORD;
+ nLineCount = 0;
+ break;
+ case NEED_RECORD :
+ b1 = GetC(); // Recordtyp einlesen
+ if (Eof()) {
+ m_acPages[GetPageCount()-1]->height = nLineCount;
+ state = LAST_PAGE;
+ } else if (b1 == 0) {
+ // variable Anzahl Bytes folgt
+ b1 = GetC(); // LSB
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ b2 = GetC(); // MSB
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ w = ((b2 << 8) | b1);
+ Seek(w, CFile::sk_current); // Skip data
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ ++nLineCount;
+ } else if (b1 < 217) {
+ // normale Anzahl BYTEs folgt
+ Seek((long)b1, CFile::sk_current); // Skip data
+ if (Eof()) {
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ }
+ ++nLineCount;
+ } else if (b1 < 254) {
+ // Whiteskip
+ nLineCount+=(b1 - 216);
+ } else if (b1 < 255) {
+ // 254 -> Pageheader
+ m_acPages[GetPageCount()-1]->height = nLineCount;
+ nLineCount = 0;
+ b1 = GetC(); // Recordlaenge (normalerweise 0x10)
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ if (b1 == 0) {
+ state = LAST_PAGE;
+ } else {
+ state = NEED_PAGEHEADER;
+ }
+ } else {
+ // Fehlerhafte Zeile oder Benutzerinfo
+ b1 = GetC(); // LSB
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ if (b1 == 0) {
+ ++nLineCount;
+ } else {
+ Seek(b1, CFile::sk_current); // Skip user info
+ if (Eof())
+ throw CSimpleException(CSimpleException::err_corruptfile);
+ }
+ }
+ break;
+ case LAST_PAGE :
+ break;
+ }
+ } while(state != LAST_PAGE);
+ return;
+}
+
+bool CSffFile::PageIsValid(int nPage)
+{
+ return ((nPage >= 0) && (nPage < GetPageCount()));
+}
+
+bool CSffFile::SeekPage(int nPage)
+{
+ if (!PageIsValid(nPage))
+ return false;
+ Seek(m_acPages[nPage]->filepos, CFile::sk_from_start);
+ return true;
+}
+
+TSFFPage *CSffFile::GetPage(int nPage)
+{
+ return PageIsValid(nPage) ? m_acPages[nPage] : (TSFFPage *)NULL;
+}
+
+bool CSffFile::IsLowRes(int nPage)
+{
+ return PageIsValid(nPage) && (m_acPages[nPage]->lpi == 98);
+}
+
+sff_word CSffFile::GetHorizontalResolution(int nPage)
+{
+ return PageIsValid(nPage) ? m_acPages[nPage]->dpi :0;
+}
+
+sff_word CSffFile::GetVerticalResolution(int nPage)
+{
+ return PageIsValid(nPage) ? m_acPages[nPage]->lpi :0;
+}
+
+sff_dword CSffFile::GetPageWidth(int nPage)
+{
+ return PageIsValid(nPage) ? m_acPages[nPage]->width :0;
+}
+
+sff_dword CSffFile::GetPageHeight(int nPage)
+{
+ return PageIsValid(nPage) ? m_acPages[nPage]->height :0;
+}
+
+bool CSffFile::GetRecord(TSFFRecord& rec)
+{
+ sff_byte b1, b2;
+ sff_word w;
+ bool result;
+
+ if (Eof()) {
+ return false;
+ }
+
+ b1 = GetC(); // Recordtyp einlesen
+ if (Eof()) {
+ result = false;
+ } else if (b1 == 0) {
+ // variable Anzahl Bytes folgt
+ b1 = GetC(); // LSB
+ b2 = GetC(); // MSB
+ w = ((b2 << 8) | b1);
+ rec.type = NORMAL;
+ rec.cb = w;
+ rec.pData = (sff_byte *)malloc(w);
+ Read(rec.pData, w);
+ result = true;
+ } else if (b1 < 217) {
+ // normale Anzahl BYTEs folgt
+ rec.type = NORMAL;
+ rec.cb = b1;
+ rec.pData = (sff_byte *)malloc(b1);
+ Read(rec.pData, b1);
+ result = true;
+ } else if (b1 < 254) {
+ // Whiteskip
+ rec.type = WHITESKIP;
+ rec.cb = (b1 - 216);
+ rec.pData = 0;
+ result = true;
+ } else if (b1 < 255) {
+ // 254 -> Pageheader
+ result = false;
+ } else {
+ // Fehlerhafte Zeile oder Benutzerinfo
+ b1 = GetC(); // LSB
+ if (b1 == 0) {
+ rec.type = BADLINE;
+ rec.cb = 1;
+ rec.pData = 0;
+ } else {
+ rec.type = USERINFO;
+ rec.cb = b1;
+ rec.pData = (sff_byte *)malloc(b1);
+ Read(rec.pData, b1);
+ }
+ result = true;
+ }
+ return result;
+}
+
+bool CSffFile::DecodeRecord(TSFFRecord& rec, IBitSink& bitsink)
+{
+ bool rc;
+
+ if (rec.type != NORMAL)
+ return false;
+
+ CHuffDecoder source(rec.pData, rec.cb);
+
+ try {
+ rec.runlength = source.DecodeLine(bitsink);
+ rc = true;
+ }
+ catch(CSimpleException e)
+ {
+ cerr << "ERROR: " << e.what() << endl;
+ rc = false;
+ }
+ return rc;
+}
diff --git a/sffview/tags/REL0_5_0/sfffile.h b/sffview/tags/REL0_5_0/sfffile.h
new file mode 100644
index 0000000..6ab24a3
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sfffile.h
@@ -0,0 +1,121 @@
+#ifndef SFFFILE_H
+#define SFFFILE_H
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: sfffile.h,v 1.2 2008/03/21 13:47:01 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#include
+
+class CBitSink;
+
+typedef enum {
+ NORMAL,
+ WHITESKIP,
+ BADLINE,
+ USERINFO
+} TSFFRecordType;
+
+typedef struct{
+ sff_dword sff_id;
+ sff_byte version;
+ sff_byte reserved;
+ sff_word user_info;
+ sff_word num_pages;
+ sff_word first_page;
+ sff_dword last_page;
+ sff_dword file_size;
+} TSFFFileHeader;
+
+typedef struct{
+ sff_byte vert_res;
+ sff_byte horiz_res;
+ sff_byte coding;
+ sff_byte specials;
+ sff_word linelen;
+ sff_word pagelen;
+ sff_dword prev_page;
+ sff_dword next_page;
+} TSFFPageHeader;
+
+typedef struct{
+ TSFFRecordType type;
+ sff_word cb;
+ sff_dword runlength;
+ sff_byte *pData;
+} TSFFRecord;
+
+typedef struct{
+ sff_dword width;
+ sff_dword height;
+ sff_word dpi;
+ sff_word lpi;
+ off_t filepos;
+} TSFFPage;
+
+//-----------------------------------------------------------------
+
+typedef std::vector PAGEVECTOR;
+
+//-----------------------------------------------------------------
+
+class CSffFile : public CFile
+{
+protected:
+ static sff_byte m_SFFID[4];
+ PAGEVECTOR m_acPages;
+
+ void ScanFile();
+ // throw CSimpleException
+
+public:
+ CSffFile(const std::string& strFileName);
+ ~CSffFile();
+
+ int GetPageCount() { return m_acPages.size(); };
+
+ bool PageIsValid(int nPage);
+ bool SeekPage(int nPage);
+ TSFFPage *GetPage(int nPage);
+
+ bool IsLowRes(int nPage);
+
+ sff_word GetHorizontalResolution(int nPage);
+ sff_word GetVerticalResolution(int nPage);
+
+ sff_dword GetPageWidth(int nPage);
+ sff_dword GetPageHeight(int nPage);
+
+ bool GetRecord(TSFFRecord& rec);
+ bool DecodeRecord(TSFFRecord& rec, IBitSink& bitsink);
+};
+
+#endif // SFFFILE_H
diff --git a/sffview/tags/REL0_5_0/sfftypes.h b/sffview/tags/REL0_5_0/sfftypes.h
new file mode 100644
index 0000000..505b78f
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sfftypes.h
@@ -0,0 +1,61 @@
+#ifndef __SFFTYPES_H__
+#define __SFFTYPES_H__
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+ $Id: sfftypes.h,v 1.2 2008/03/21 13:47:02 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+#if !defined(__WINDOWS__) && (defined(_WINDOWS) || defined(_Windows))
+#define __WINDOWS__
+#endif
+#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
+#define __WIN32__
+#endif
+#if defined(__WIN32__) || defined(__WINDOWS__)
+#include
+#ifdef __WIN32__
+DECLARE_HANDLE(uhandle_t); /* Win32 file handle */
+#else
+typedef HFILE uhandle_t; /* Windows file handle */
+#endif
+#else
+typedef void* uhandle_t; /* client data handle */
+#endif
+
+typedef unsigned char sff_byte;
+typedef unsigned short sff_word;
+typedef unsigned int sff_dword;
+
+#ifndef _MAX_PATH
+#define _MAX_PATH 256
+#endif
+
+#endif // __SFFTYPES_H__
diff --git a/sffview/tags/REL0_5_0/sffview.cpp b/sffview/tags/REL0_5_0/sffview.cpp
new file mode 100644
index 0000000..0df84bd
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sffview.cpp
@@ -0,0 +1,221 @@
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "sfftypes.h"
+#include "common.h"
+#include "codes.h"
+#include "decoder.h"
+#include "sfffile.h"
+#include "sffview.h"
+#include "sffapp.h"
+#include "sffdoc.h"
+
+//-----------------------------------------------------------------------------
+// SffView
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(SffView, wxView)
+
+BEGIN_EVENT_TABLE(SffView, wxView)
+END_EVENT_TABLE()
+
+SffView::~SffView()
+{
+ if (m_pMemDC)
+ delete m_pMemDC;
+}
+
+// What to do when a view is created. Creates actual
+// windows for displaying the view.
+bool SffView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
+{
+ m_pMemDC = new wxMemoryDC();
+
+ m_nZoom = 1.0;
+ m_bXFlipped = false;
+ m_bYFlipped = false;
+
+ m_nScaleType = FITWIDTH;
+
+ frame = GetMainFrame();
+ canvas = GetMainFrame()->canvas;
+ canvas->view = this;
+
+ // Associate the appropriate frame with this view.
+ SetFrame(frame);
+
+ // Make sure the document manager knows that this is the
+ // current view.
+ Activate(TRUE);
+
+ // Initialize the edit menu Undo and Redo items
+ doc->GetCommandProcessor()->Initialize();
+
+ return TRUE;
+}
+
+void SffView::SetBitmap(wxBitmap *pBmp)
+{
+ if (pBmp) {
+ m_pMemDC->SelectObject(*pBmp);
+ m_nBitmapHeight = pBmp->GetHeight();
+ m_nBitmapWidth = pBmp->GetWidth();
+ CalcScale();
+ } else {
+ m_pMemDC->SelectObject(wxNullBitmap);
+ m_nBitmapHeight = m_nBitmapWidth = 0;
+ }
+}
+
+void SffView::SetScale(TScale type)
+{
+ TScale old = m_nScaleType;
+ m_nScaleType = type;
+ if (m_nScaleType != old) {
+ CalcScale();
+ canvas->Refresh();
+ }
+}
+
+void SffView::CalcScale()
+{
+ int w, h;
+ switch (m_nScaleType)
+ {
+ case FULLSCALE:
+ m_nZoom=1;
+ canvas->SetScrollbars( 1, 1, m_nBitmapWidth, m_nBitmapHeight);
+ canvas->Refresh();
+ break;
+ case FITWIDTH:
+ frame->GetClientSize(&w, &h);
+ m_nZoom=w; m_nZoom = m_nZoom/m_nBitmapWidth;
+ canvas->SetScrollbars( 1, 1, 1, (int)(m_nBitmapHeight*m_nZoom));
+ canvas->Refresh();
+ break;
+ case FULLPAGE:
+ frame->GetClientSize(&w, &h);
+ m_nZoom=h; m_nZoom /= m_nBitmapHeight;
+ canvas->SetScrollbars( 1, 1, (int)(m_nBitmapWidth*m_nZoom), 1);
+ canvas->Refresh();
+ break;
+ }
+}
+
+void SffView::OnDraw(wxDC *dc)
+{
+ // Flipping is currently not supported due to wxGTK not honouring
+ // the mapping mode while blitting. This seems to be badly horked
+ // currently (wxGTK 2.5.2)
+ dc->SetUserScale(m_nZoom, m_nZoom);
+#if defined(__WXGTK__) && !wxCHECK_VERSION(2,8,0)
+ if (m_nZoom != 1) {
+ // Strange misbehaviour of wxGTK -> if we blit zoomed, the colours
+ // get inversed ??!? Workaround: wxSRC_INVERT
+ dc->Blit(0,0,m_nBitmapWidth,m_nBitmapHeight,m_pMemDC,0,0,wxSRC_INVERT);
+ } else {
+ dc->Blit(0,0,m_nBitmapWidth,m_nBitmapHeight,m_pMemDC,0,0,wxCOPY);
+ }
+#else
+ dc->Blit(0,0,m_nBitmapWidth,m_nBitmapHeight,m_pMemDC,0,0,wxCOPY);
+#endif
+}
+
+void SffView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
+{
+ if (canvas) {
+ SetBitmap(((SffDocument *)GetDocument())->GetPageBitmap());
+ canvas->Refresh();
+ }
+}
+
+void SffView::FlipX()
+{
+ m_bXFlipped = !m_bXFlipped;
+ canvas->Refresh();
+}
+
+void SffView::FlipY()
+{
+ m_bYFlipped = !m_bYFlipped;
+ canvas->Refresh();
+}
+
+// Clean up windows used for displaying the view.
+bool SffView::OnClose(bool deleteWindow)
+{
+ if (!GetDocument()->Close())
+ return FALSE;
+
+ canvas->view = (wxView *) NULL;
+ canvas = (SffCanvas *) NULL;
+
+ wxString s(wxTheApp->GetAppName());
+ if (frame) frame->SetTitle(s);
+
+ SetFrame((wxFrame *) NULL);
+
+ Activate(FALSE);
+
+ return TRUE;
+}
+
+wxPrintout* SffView::OnCreatePrintout()
+{
+ return new SffPrintout((SffDocument *)GetDocument());
+}
+
+//-----------------------------------------------------------------------------
+// SffCanvas
+//-----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(SffCanvas, wxScrolledWindow)
+END_EVENT_TABLE()
+
+// Define a constructor for my canvas
+SffCanvas::SffCanvas(wxView *v, wxFrame *frame,
+ const wxPoint& pos, const wxSize& size) :
+ wxScrolledWindow(frame, -1, pos, size, wxSUNKEN_BORDER)
+{
+ view = v;
+ SetBackgroundColour(_T("WHITE"));
+}
+
+// Define the repainting behaviour
+void SffCanvas::OnDraw(wxDC& dc)
+{
+ if (view) {
+ view->OnDraw(&dc);
+ }
+}
diff --git a/sffview/tags/REL0_5_0/sffview.h b/sffview/tags/REL0_5_0/sffview.h
new file mode 100644
index 0000000..6f956b6
--- /dev/null
+++ b/sffview/tags/REL0_5_0/sffview.h
@@ -0,0 +1,103 @@
+#ifndef __SFFVIEW_H__
+#define __SFFVIEW_H__
+//
+// This file is part of sffview, a program to view structured fax files (sff)
+//
+// Copyright (C) 1998-2012 Peter Schaefer-Hutter and contributors ("THE AUTHORS")
+//
+// Permission to use, copy, modify, distribute, and sell this software and
+// its documentation for any purpose is hereby granted without fee.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+//
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
+// INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
+// DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
+// THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
+// OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Contributor(s):
+// None
+//
+// You can contact the original author by email at peter.schaefer@gmx.de.
+//
+// I'm always pleased to hear that somebody is actually using my software.
+// If you can manage it, e-mail me a quick notice. Thanks!
+//
+/*-RCS-Info----------------------------------------------------
+
+$Id: sffview.h,v 1.3 2011/10/18 19:39:38 pschaefer Exp $
+
+---RCS-Info--------------------------------------------------*/
+
+// ----------------------------------------------------------------------------
+// Class declarations
+// ----------------------------------------------------------------------------
+
+class SffCanvas : public wxScrolledWindow
+{
+public:
+ wxView *view;
+
+ SffCanvas(wxView *v, wxFrame *frame,
+ const wxPoint& pos,
+ const wxSize& size);
+
+ virtual void OnDraw(wxDC& dc);
+
+ void OnMouseEvent(wxMouseEvent& event);
+
+ DECLARE_EVENT_TABLE()
+};
+
+class SffView : public wxView
+{
+ DECLARE_DYNAMIC_CLASS(SffView)
+
+public:
+ enum TScale {
+ FULLSCALE,
+ FULLPAGE,
+ FITWIDTH
+ };
+
+protected:
+ wxMemoryDC *m_pMemDC;
+ wxUint32 m_nBitmapWidth;
+ wxUint32 m_nBitmapHeight;
+
+ double m_nZoom;
+ bool m_bXFlipped;
+ bool m_bYFlipped;
+
+ TScale m_nScaleType;
+
+ void SetBitmap(wxBitmap *pBmp);
+
+public:
+ wxFrame *frame;
+ SffCanvas *canvas;
+
+ SffView() { canvas = (SffCanvas *)NULL; frame = (wxFrame *) NULL; };
+ virtual ~SffView();
+
+ void FlipX();
+ void FlipY();
+
+ void SetScale(TScale type);
+ void CalcScale();
+
+ bool OnCreate(wxDocument *doc, long flags);
+ void OnDraw(wxDC *dc);
+ void OnUpdate(wxView *sender, wxObject *hint = (wxObject *) NULL);
+ bool OnClose(bool deleteWindow = TRUE);
+
+ virtual wxPrintout* OnCreatePrintout();
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // __SFFVIEW_H__
diff --git a/sffview/tags/REL0_5_0/testfax.sff b/sffview/tags/REL0_5_0/testfax.sff
new file mode 100644
index 0000000..7d24a2e
Binary files /dev/null and b/sffview/tags/REL0_5_0/testfax.sff differ
diff --git a/sffview/tags/REL0_5_0/win32/Makefile.vc b/sffview/tags/REL0_5_0/win32/Makefile.vc
new file mode 100644
index 0000000..571699d
--- /dev/null
+++ b/sffview/tags/REL0_5_0/win32/Makefile.vc
@@ -0,0 +1,75 @@
+#
+# Makefile for MS Visual C (nmake)
+#
+# Build command:
+# nmake /f makefile.vc
+#
+# Without debug info:
+# nmake nodebug=1 /f makefile.vc
+
+!include
+
+WXBASE = C:\wxWidgets-2.9.4
+
+WXLIBPATH = $(WXBASE)\lib\vc_lib
+
+!IFDEF NODEBUG
+WXCONFPATH = $(WXBASE)\lib\vc_lib\mswu
+WXLIBS = /LIBPATH:$(WXLIBPATH) wxbase29u.lib wxbase29u_net.lib wxmsw29u_core.lib \
+ wxmsw29u_aui.lib wxmsw29u_adv.lib wxmsw29u_ribbon.lib \
+ wxmsw29u_html.lib wxbase29u_xml.lib wxpng.lib wxtiff.lib \
+ wxjpeg.lib wxzlib.lib wxregexu.lib wxexpat.lib
+!ELSE
+WXCONFPATH = $(WXBASE)\lib\vc_lib\mswud
+WXLIBS = /LIBPATH:$(WXLIBPATH) wxbase29ud.lib wxbase29ud_net.lib wxmsw29ud_core.lib \
+ wxmsw29ud_aui.lib wxmsw29ud_adv.lib wxmsw29ud_ribbon.lib \
+ wxmsw29ud_html.lib wxbase29ud_xml.lib wxpngd.lib wxtiffd.lib \
+ wxjpegd.lib wxzlibd.lib wxregexud.lib wxexpatd.lib
+!ENDIF
+
+INCL = /I. /I$(WXCONFPATH) /I$(WXBASE)\include
+
+EXE=sffview.exe
+
+CFLAGS= /D_CRT_SECURE_NO_DEPRECATE $(cflags) $(cdebug) $(cvarsmt)
+CPPFLAGS= /EHsc /D_CRT_SECURE_NO_DEPRECATE $(INCL) $(cppflags) $(cflags) $(cdebug) $(cvarsmt)
+LDFLAGS= $(ldebug) $(guilflags)
+LDLIBS= $(guilibs) $(olelibs) $(WXLIBS) advapi32.lib shell32.lib comctl32.lib rpcrt4.lib
+
+RCFLAGS = $(rcflags) /i$(WXBASE)\include
+
+OBJ = \
+ ..\codes.obj \
+ ..\common.obj \
+ ..\decoder.obj \
+ ..\sffapp.obj \
+ ..\sffdoc.obj \
+ ..\sfffile.obj \
+ ..\sffview.obj \
+ sffview.res
+
+# Template command for compiling .c to .obj
+.c.obj:
+ $(cc) $(CFLAGS) $*.c /Fo$@
+
+# Template command for compiling .c to .obj
+.cpp.obj:
+ $(CPP) $(CPPFLAGS) $*.cpp /Fo$@
+
+# Template command for compiling .rc to .res
+.rc.res:
+ $(RC) $(RCFLAGS) /fo$@ $*.rc
+
+all: $(EXE)
+
+$(EXE): $(OBJ)
+ $(link) $(LDFLAGS) $(LDLIBS) $(OBJ) -out:$(EXE)
+
+clean:
+ -del *.exe
+ -del *.ilk
+ -del *.exp
+ -del *.pdb
+ -del *.manifest
+ -del RC*
+ -del $(OBJ)
diff --git a/sffview/tags/REL0_5_0/win32/build_vc.cmd b/sffview/tags/REL0_5_0/win32/build_vc.cmd
new file mode 100644
index 0000000..92391b3
--- /dev/null
+++ b/sffview/tags/REL0_5_0/win32/build_vc.cmd
@@ -0,0 +1,3 @@
+@echo off
+call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
+nmake nodebug=1 /f makefile.vc %1
diff --git a/sffview/tags/REL0_5_0/win32/sffview.ico b/sffview/tags/REL0_5_0/win32/sffview.ico
new file mode 100644
index 0000000..d46a53a
Binary files /dev/null and b/sffview/tags/REL0_5_0/win32/sffview.ico differ
diff --git a/sffview/tags/REL0_5_0/win32/sffview.rc b/sffview/tags/REL0_5_0/win32/sffview.rc
new file mode 100644
index 0000000..2531710
--- /dev/null
+++ b/sffview/tags/REL0_5_0/win32/sffview.rc
@@ -0,0 +1,16 @@
+sffview ICON "sffview.ico"
+
+#include "wx/msw/wx.rc"
+
+open BITMAP "../bitmaps/open.bmp"
+print BITMAP "../bitmaps/print.bmp"
+help BITMAP "../bitmaps/help.bmp"
+prev BITMAP "../bitmaps/prev.bmp"
+next BITMAP "../bitmaps/next.bmp"
+zoomin BITMAP "../bitmaps/zoomin.bmp"
+zoomout BITMAP "../bitmaps/zoomout.bmp"
+flipx BITMAP "../bitmaps/flipx.bmp"
+flipy BITMAP "../bitmaps/flipy.bmp"
+fit_window BITMAP "../bitmaps/fit_window.bmp"
+fit_width BITMAP "../bitmaps/fit_width.bmp"
+actual_size BITMAP "../bitmaps/actual_size.bmp"