summaryrefslogtreecommitdiff
path: root/im/src
diff options
context:
space:
mode:
Diffstat (limited to 'im/src')
-rwxr-xr-xim/src/COPYRIGHT32
-rwxr-xr-xim/src/Makefile15
-rwxr-xr-xim/src/README11
-rwxr-xr-xim/src/config.mak89
-rwxr-xr-xim/src/im.def200
-rw-r--r--im/src/im.dep121
-rwxr-xr-xim/src/im.rc19
-rwxr-xr-xim/src/im_attrib.cpp319
-rwxr-xr-xim/src/im_bin.cpp111
-rwxr-xr-xim/src/im_binfile.cpp710
-rwxr-xr-xim/src/im_capture.def27
-rwxr-xr-xim/src/im_capture.mak73
-rw-r--r--im/src/im_capture.wlib22
-rwxr-xr-xim/src/im_capture_dx.cpp2255
-rwxr-xr-xim/src/im_colorhsi.cpp265
-rwxr-xr-xim/src/im_colormode.cpp87
-rwxr-xr-xim/src/im_colorutil.cpp27
-rwxr-xr-xim/src/im_convertbitmap.cpp284
-rwxr-xr-xim/src/im_convertcolor.cpp985
-rwxr-xr-xim/src/im_converttype.cpp555
-rwxr-xr-xim/src/im_counter.cpp151
-rwxr-xr-xim/src/im_datatype.cpp54
-rwxr-xr-xim/src/im_dib.cpp1136
-rwxr-xr-xim/src/im_dibxbitmap.cpp181
-rwxr-xr-xim/src/im_ecw.def2
-rwxr-xr-xim/src/im_ecw.mak16
-rwxr-xr-xim/src/im_file.cpp465
-rwxr-xr-xim/src/im_filebuffer.cpp695
-rwxr-xr-xim/src/im_fileraw.cpp66
-rwxr-xr-xim/src/im_format.cpp299
-rwxr-xr-xim/src/im_format_all.cpp34
-rwxr-xr-xim/src/im_format_bmp.cpp949
-rwxr-xr-xim/src/im_format_ecw.cpp385
-rwxr-xr-xim/src/im_format_gif.cpp1510
-rwxr-xr-xim/src/im_format_ico.cpp660
-rwxr-xr-xim/src/im_format_krn.cpp325
-rwxr-xr-xim/src/im_format_led.cpp341
-rwxr-xr-xim/src/im_format_pcx.cpp711
-rwxr-xr-xim/src/im_format_pnm.cpp483
-rwxr-xr-xim/src/im_format_ras.cpp608
-rwxr-xr-xim/src/im_format_raw.cpp366
-rwxr-xr-xim/src/im_format_sgi.cpp616
-rwxr-xr-xim/src/im_format_tga.cpp1113
-rwxr-xr-xim/src/im_format_wmv.cpp1633
-rwxr-xr-xim/src/im_image.cpp695
-rwxr-xr-xim/src/im_lib.cpp38
-rwxr-xr-xim/src/im_lua3.c1297
-rwxr-xr-xim/src/im_palette.cpp551
-rwxr-xr-xim/src/im_process.def165
-rw-r--r--im/src/im_process.dep84
-rwxr-xr-xim/src/im_process.mak36
-rwxr-xr-xim/src/im_rgb2map.cpp964
-rwxr-xr-xim/src/im_str.cpp67
-rwxr-xr-xim/src/im_sysfile_unix.cpp211
-rwxr-xr-xim/src/im_sysfile_win32.cpp207
-rwxr-xr-xim/src/im_wmv.def2
-rwxr-xr-xim/src/im_wmv.mak23
-rwxr-xr-xim/src/imlua3.def2
-rwxr-xr-xim/src/imlua3.mak12
-rwxr-xr-xim/src/imlua5.mak18
-rw-r--r--im/src/imlua51.dep38
-rwxr-xr-xim/src/imlua_capture5.mak18
-rwxr-xr-xim/src/imlua_process5.mak19
-rw-r--r--im/src/imlua_process51.dep17
-rwxr-xr-xim/src/imlua_wmv.mak17
-rwxr-xr-xim/src/jas_binfile.c97
-rwxr-xr-xim/src/lua5/im_convert.lua18
-rwxr-xr-xim/src/lua5/im_fftw.lua57
-rwxr-xr-xim/src/lua5/im_image.lua24
-rwxr-xr-xim/src/lua5/im_process.lua329
-rwxr-xr-xim/src/lua5/imlua.c252
-rwxr-xr-xim/src/lua5/imlua.def24
-rwxr-xr-xim/src/lua5/imlua_aux.c256
-rwxr-xr-xim/src/lua5/imlua_aux.h82
-rwxr-xr-xim/src/lua5/imlua_avi.c44
-rwxr-xr-xim/src/lua5/imlua_avi.def4
-rwxr-xr-xim/src/lua5/imlua_capture.c443
-rwxr-xr-xim/src/lua5/imlua_capture.def5
-rwxr-xr-xim/src/lua5/imlua_convert.c96
-rwxr-xr-xim/src/lua5/imlua_fftw.c162
-rwxr-xr-xim/src/lua5/imlua_fftw.def4
-rwxr-xr-xim/src/lua5/imlua_file.c661
-rwxr-xr-xim/src/lua5/imlua_image.c1083
-rwxr-xr-xim/src/lua5/imlua_image.h38
-rwxr-xr-xim/src/lua5/imlua_jp2.c44
-rwxr-xr-xim/src/lua5/imlua_jp2.def4
-rwxr-xr-xim/src/lua5/imlua_kernel.c182
-rwxr-xr-xim/src/lua5/imlua_palette.c399
-rwxr-xr-xim/src/lua5/imlua_palette.h32
-rwxr-xr-xim/src/lua5/imlua_process.c3143
-rwxr-xr-xim/src/lua5/imlua_process.def4
-rwxr-xr-xim/src/lua5/imlua_util.c279
-rwxr-xr-xim/src/lua5/imlua_wmv.c44
-rwxr-xr-xim/src/lua5/imlua_wmv.def4
-rw-r--r--im/src/lua5/loh/im_convert.loh87
-rwxr-xr-xim/src/lua5/loh/im_convert_be32.loh87
-rw-r--r--im/src/lua5/loh/im_convert_be64.loh95
-rwxr-xr-xim/src/lua5/loh/im_convert_le64.loh95
-rwxr-xr-xim/src/lua5/loh/im_fftw.loh110
-rwxr-xr-xim/src/lua5/loh/im_fftw_be32.loh110
-rw-r--r--im/src/lua5/loh/im_fftw_be64.loh122
-rwxr-xr-xim/src/lua5/loh/im_fftw_le64.loh122
-rwxr-xr-xim/src/lua5/loh/im_fftw_le64w.loh115
-rw-r--r--im/src/lua5/loh/im_image.loh63
-rwxr-xr-xim/src/lua5/loh/im_image_be32.loh63
-rw-r--r--im/src/lua5/loh/im_image_be64.loh68
-rwxr-xr-xim/src/lua5/loh/im_image_le64.loh68
-rwxr-xr-xim/src/lua5/loh/im_process.loh817
-rwxr-xr-xim/src/lua5/loh/im_process_be32.loh817
-rw-r--r--im/src/lua5/loh/im_process_be64.loh897
-rwxr-xr-xim/src/lua5/loh/im_process_le64.loh897
-rwxr-xr-xim/src/lua5/loh/im_process_le64w.loh890
-rwxr-xr-xim/src/make_uname13
-rwxr-xr-xim/src/make_uname.bat74
-rwxr-xr-xim/src/old_im.cpp440
-rwxr-xr-xim/src/old_imcolor.c75
-rwxr-xr-xim/src/old_imresize.c117
-rwxr-xr-xim/src/process/im_analyze.cpp1268
-rwxr-xr-xim/src/process/im_arithmetic_bin.cpp587
-rwxr-xr-xim/src/process/im_arithmetic_un.cpp256
-rwxr-xr-xim/src/process/im_canny.cpp254
-rwxr-xr-xim/src/process/im_color.cpp255
-rwxr-xr-xim/src/process/im_convolve.cpp1594
-rwxr-xr-xim/src/process/im_convolve_rank.cpp701
-rwxr-xr-xim/src/process/im_distance.cpp512
-rwxr-xr-xim/src/process/im_effects.cpp86
-rwxr-xr-xim/src/process/im_fft.cpp198
-rwxr-xr-xim/src/process/im_geometric.cpp724
-rwxr-xr-xim/src/process/im_histogram.cpp105
-rwxr-xr-xim/src/process/im_houghline.cpp435
-rwxr-xr-xim/src/process/im_kernel.cpp293
-rwxr-xr-xim/src/process/im_logic.cpp136
-rwxr-xr-xim/src/process/im_morphology_bin.cpp317
-rwxr-xr-xim/src/process/im_morphology_gray.cpp231
-rwxr-xr-xim/src/process/im_quantize.cpp64
-rwxr-xr-xim/src/process/im_render.cpp532
-rwxr-xr-xim/src/process/im_resize.cpp332
-rwxr-xr-xim/src/process/im_statistics.cpp341
-rwxr-xr-xim/src/process/im_threshold.cpp391
-rwxr-xr-xim/src/process/im_tonegamut.cpp322
-rwxr-xr-xim/src/tecmake_compact.mak1170
141 files changed, 48647 insertions, 0 deletions
diff --git a/im/src/COPYRIGHT b/im/src/COPYRIGHT
new file mode 100755
index 0000000..ca0b899
--- /dev/null
+++ b/im/src/COPYRIGHT
@@ -0,0 +1,32 @@
+IM License
+-----------
+
+IM is licensed under the terms of the MIT license reproduced below.
+This means that IM is free software and can be used for both academic
+and commercial purposes at absolutely no cost.
+
+===============================================================================
+
+Copyright (C) 1994-2009 Tecgraf, PUC-Rio.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+===============================================================================
+
+(end of COPYRIGHT)
diff --git a/im/src/Makefile b/im/src/Makefile
new file mode 100755
index 0000000..3fe5908
--- /dev/null
+++ b/im/src/Makefile
@@ -0,0 +1,15 @@
+
+.PHONY: do_all im im_jp2 im_process imlua3 imlua5 imlua_jp2 imlua_process5
+#do_all: im im_jp2 im_process im_fftw imlua3 imlua5 imlua_jp2 imlua_process5 imlua_fftw5
+do_all: im im_process imlua5 imlua_jp2 imlua_process5
+
+im:
+ $(MAKE) --no-print-directory -f tecmake_compact.mak
+im_process:
+ @$(MAKE) --no-print-directory -f tecmake_compact.mak MF=im_process
+imlua3:
+ @$(MAKE) --no-print-directory -f tecmake_compact.mak MF=imlua3
+imlua5:
+ @$(MAKE) --no-print-directory -f tecmake_compact.mak MF=imlua5
+imlua_process5:
+ @$(MAKE) --no-print-directory -f tecmake_compact.mak MF=imlua_process5
diff --git a/im/src/README b/im/src/README
new file mode 100755
index 0000000..3dbcbd5
--- /dev/null
+++ b/im/src/README
@@ -0,0 +1,11 @@
+README for IM
+
+ IM is a toolkit for Digital Imaging. IM is based on 4 concepts: Image Representation, Storage, Processing and Capture. The main goal of the library is to provide a simple API and abstraction of images for scientific applications.
+ The most popular file formats are supported: TIFF, BMP, PNG, JPEG, GIF and AVI. Image representation includes scientific data types. About a hundred Image Processing operations are available.
+
+ Build instructions and usage are available in the IM documentation.
+
+ For complete information, visit IM's web site at http://www.tecgraf.puc-rio.br/im
+ or access its documentation in the HTML folder.
+
+(end of README)
diff --git a/im/src/config.mak b/im/src/config.mak
new file mode 100755
index 0000000..a938100
--- /dev/null
+++ b/im/src/config.mak
@@ -0,0 +1,89 @@
+PROJNAME = im
+LIBNAME = im
+OPT = YES
+
+INCLUDES = . ../include
+
+# WORDS_BIGENDIAN used by libTIFF
+ifeq ($(TEC_SYSARCH), ppc)
+ DEFINES = WORDS_BIGENDIAN
+endif
+ifeq ($(TEC_SYSARCH), mips)
+ DEFINES = WORDS_BIGENDIAN
+endif
+ifeq ($(TEC_SYSARCH), sparc)
+ DEFINES = WORDS_BIGENDIAN
+endif
+
+SRC = \
+ old_imcolor.c old_imresize.c im_converttype.cpp \
+ im_attrib.cpp im_format.cpp im_format_tga.cpp im_filebuffer.cpp \
+ im_bin.cpp im_format_all.cpp im_format_raw.cpp \
+ im_binfile.cpp im_format_sgi.cpp im_datatype.cpp im_format_pcx.cpp \
+ im_colorhsi.cpp im_format_bmp.cpp im_image.cpp im_rgb2map.cpp \
+ im_colormode.cpp im_format_gif.cpp im_lib.cpp im_format_pnm.cpp \
+ im_colorutil.cpp im_format_ico.cpp im_palette.cpp \
+ im_convertbitmap.cpp im_format_led.cpp im_counter.cpp im_str.cpp \
+ im_convertcolor.cpp im_fileraw.cpp im_format_krn.cpp \
+ im_file.cpp im_format_ras.cpp old_im.cpp \
+ $(SRCJPEG) $(SRCTIFF) $(SRCPNG) $(SRCZLIB) $(SRCLZF)
+
+
+ifneq ($(findstring Win, $(TEC_SYSNAME)), )
+ SRC += im_sysfile_win32.cpp im_dib.cpp im_dibxbitmap.cpp
+
+ ifneq ($(findstring dll, $(TEC_UNAME)), )
+ SRC += im.rc
+ endif
+
+ ifeq ($(findstring _64, $(TEC_UNAME)), )
+ # optimize PNG lib for VC
+ ifneq ($(findstring vc, $(TEC_UNAME)), )
+ SRC += libpng/pngvcrd.c
+ DEFINES += PNG_USE_PNGVCRD
+ endif
+ ifneq ($(findstring dll, $(TEC_UNAME)), )
+ SRC += libpng/pngvcrd.c
+ DEFINES += PNG_USE_PNGVCRD
+ endif
+ endif
+
+ # force the definition of math functions using float
+ # Watcom does not define them
+ ifneq ($(findstring ow, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+ endif
+
+ ifneq ($(findstring bc, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+ else
+ USE_EXIF = Yes
+ endif
+else
+ SRC += im_sysfile_unix.cpp
+endif
+
+ifdef USE_EXIF
+ SRC += $(SRCEXIF)
+ DEFINES += USE_EXIF
+endif
+
+ifneq ($(findstring Linux, $(TEC_UNAME)), )
+ # optimize PNG lib for Linux in x86
+ ifeq "$(TEC_SYSARCH)" "x86"
+ SRC += libpng/pnggccrd.c
+ DEFINES += PNG_USE_PNGGCCRD
+ endif
+endif
+
+ifneq ($(findstring AIX, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+endif
+
+ifneq ($(findstring SunOS, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+endif
+
+ifneq ($(findstring HP-UX, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+endif
diff --git a/im/src/im.def b/im/src/im.def
new file mode 100755
index 0000000..41aa175
--- /dev/null
+++ b/im/src/im.def
@@ -0,0 +1,200 @@
+EXPORTS
+ imFileGetAttribute
+ imFileNew
+ imFileOpen
+ imFileFormat
+ imFileReadImageData
+ imFileReadImageInfo
+ imFileWriteImageData
+ imFileWriteImageInfo
+ imFileClose
+ imFileGetInfo
+ imFileGetPalette
+ imFileSetAttribute
+ imFileGetAttributeList
+ imFileSetBaseAttributes
+ imFileSetInfo
+ imFileSetPalette
+ imFileOpenAs
+ imFileHandle
+ imFileLineBufferCount
+ imFileLineSizeAligned
+ imFileLineBufferInc
+ imFileLineBufferRead
+ imFileLineBufferWrite
+ imFileImageLoad
+ imFileImageLoadBitmap
+ imFileImageSave
+ imFileLoadImageFrame
+ imFileLoadBitmapFrame
+ imFileSaveImage
+ imFileLoadBitmap
+ imFileLoadImage
+ imVersion
+ imVersionDate
+ imVersionNumber
+ imPaletteFindColor
+ imPaletteFindNearest
+ imPaletteUniformIndex
+ imPaletteUniformIndexHalftoned
+ imPaletteBlackBody
+ imPaletteBlue
+ imPaletteBlueIce
+ imPaletteCian
+ imPaletteGray
+ imPaletteGreen
+ imPaletteHotIron
+ imPaletteHues
+ imPaletteMagenta
+ imPaletteRainbow
+ imPaletteRed
+ imPaletteUniform
+ imPaletteYellow
+ imPaletteHighContrast
+ imFormatRegister
+ imFormatRegisterInternal
+ imFormatRemoveAll
+ imFormatCanWriteImage
+ imFormatCompressions
+ imFormatInfo
+ imFormatList
+ imColorModeSpaceName
+ imDataTypeName
+ imBinCPUByteOrder
+ imColorModeDepth
+ imColorModeIsBitmap
+ imColorModeToBitmap
+ imDataTypeSize
+ imStrCheck
+ imStrEqual
+ imStrNLen
+ imColorEncode
+ imDataTypeIntMin
+ imDataTypeIntMax
+ imBinSwapBytes2
+ imBinSwapBytes4
+ imBinSwapBytes8
+ imColorDecode
+ imCounterSetCallback
+ imCounterBegin
+ imCounterInc
+ imCounterIncTo
+ imCounterEnd
+ imCounterTotal
+ imAttribTableCreate
+ imAttribTableDestroy
+ imAttribTableCount
+ imAttribTableRemoveAll
+ imAttribTableGet
+ imAttribTableSet
+ imAttribTableUnSet
+ imAttribTableCopyFrom
+ imAttribTableForEach
+ imImageGetAttribute
+ imImageClone
+ imImageCreate
+ imImageDuplicate
+ imImageInit
+ imImageCheckFormat
+ imImageDataSize
+ imImageLineCount
+ imImageLineSize
+ imImageIsBitmap
+ imImageGetOpenGLData
+ imImageMatch
+ imImageMatchColor
+ imImageMatchColorSpace
+ imImageMatchDataType
+ imImageMatchSize
+ imImageClear
+ imImageCopyAttributes
+ imImageDestroy
+ imImageGetAttributeList
+ imImageReshape
+ imImageSetAttribute
+ imImageSetBinary
+ imImageMakeBinary
+ imImageMakeGray
+ imImageSetPalette
+ imImageCopy
+ imImageCopyData
+ imImageCreateBased
+ imImageAddAlpha
+ imDibToHBitmap
+ imDibLogicalPalette
+ imDibCaptureScreen
+ imDibCreate
+ imDibCreateCopy
+ imDibCreateReference
+ imDibCreateSection
+ imDibFromHBitmap
+ imDibFromImage
+ imDibLoadFile
+ imDibPasteClipboard
+ imDibLineGetPixelFunc
+ imDibLineSetPixelFunc
+ imDibToImage
+ imDibIsClipboardAvailable
+ imDibSaveFile
+ imDibCopyClipboard
+ imDibDecodeToBitmap
+ imDibDecodeToMap
+ imDibDecodeToRGBA
+ imDibDestroy
+ imDibEncodeFromBitmap
+ imDibEncodeFromMap
+ imDibEncodeFromRGBA
+ imConvertColorSpace
+ imConvertDataType
+ imConvertToBitmap
+ imConvertPacking
+ imConvertMapToRGB
+ imConvertRGB2Map
+ imFileNewRaw
+ imFileOpenRaw
+ imBinFileNew
+ imBinFileOpen
+ imBinFileByteOrder
+ imBinFileEndOfFile
+ imBinFileError
+ imBinFileRegisterModule
+ imBinFileSetCurrentModule
+ imBinFilePrintf
+ imBinFileReadInteger
+ imBinFileReadFloat
+ imBinFileRead
+ imBinFileSize
+ imBinFileTell
+ imBinFileWrite
+ imBinFileClose
+ imBinFileSeekFrom
+ imBinFileSeekOffset
+ imBinFileSeekTo
+ imColorHSI_ImaxS
+ imColorHSI2RGB
+ imColorHSI2RGBbyte
+ imColorRGB2HSI
+ imColorRGB2HSIbyte
+ imEncodeColor
+ imDecodeColor
+ imImageInfo
+ imLoadRGB
+ imSaveRGB
+ imLoadMap
+ imSaveMap
+ imRGB2Map
+ imMap2RGB
+ imRGB2Gray
+ imMap2Gray
+ imResize
+ imStretch
+ imRegisterCallback
+ imCompressDataZ
+ imCompressDataUnZ
+ imAttribArrayCreate
+ imAttribArrayGet
+ imAttribArraySet
+ imAttribArrayCopyFrom
+ imBinMemoryRelease
+ imFileImageLoadRegion
+ imFileLoadImageRegion
diff --git a/im/src/im.dep b/im/src/im.dep
new file mode 100644
index 0000000..9f83359
--- /dev/null
+++ b/im/src/im.dep
@@ -0,0 +1,121 @@
+$(OBJDIR)/old_imcolor.o: old_imcolor.c ../include/old_im.h ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_image.h \
+ ../include/im_convert.h ../include/im_image.h
+$(OBJDIR)/old_imresize.o: old_imresize.c ../include/old_im.h
+$(OBJDIR)/im_converttype.o: im_converttype.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_complex.h ../include/im_math.h \
+ ../include/im_util.h ../include/im_image.h ../include/im_convert.h \
+ ../include/im_image.h ../include/im_color.h ../include/im_counter.h
+$(OBJDIR)/im_attrib.o: im_attrib.cpp ../include/im_attrib.h \
+ ../include/im_attrib_flat.h ../include/im_util.h
+$(OBJDIR)/im_format.o: im_format.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_format.h ../include/im_file.h ../include/im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h ../include/im_util.h
+$(OBJDIR)/im_format_tga.o: im_format_tga.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h ../include/im_util.h \
+ ../include/im_format_all.h ../include/im_counter.h ../include/im_math.h \
+ ../include/im_util.h ../include/im_binfile.h
+$(OBJDIR)/im_filebuffer.o: im_filebuffer.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_format.h ../include/im_file.h ../include/im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h ../include/im_util.h \
+ ../include/im_complex.h ../include/im_math.h ../include/im_util.h \
+ ../include/im_color.h
+$(OBJDIR)/im_bin.o: im_bin.cpp ../include/im_util.h
+$(OBJDIR)/im_format_all.o: im_format_all.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_format.h ../include/im_file.h ../include/im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h
+$(OBJDIR)/im_format_raw.o: im_format_raw.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h ../include/im_util.h \
+ ../include/im_format_raw.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_binfile.o: im_binfile.cpp ../include/im_util.h ../include/im_binfile.h \
+ ../include/im_util.h
+$(OBJDIR)/im_format_sgi.o: im_format_sgi.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h ../include/im_util.h \
+ ../include/im_format_all.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_datatype.o: im_datatype.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h
+$(OBJDIR)/im_format_pcx.o: im_format_pcx.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_colorhsi.o: im_colorhsi.cpp ../include/im_colorhsi.h \
+ ../include/im_color.h ../include/im_math.h ../include/im_util.h
+$(OBJDIR)/im_format_bmp.o: im_format_bmp.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_image.o: im_image.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_util.h ../include/im_attrib.h \
+ ../include/im_attrib_flat.h ../include/im_file.h ../include/im.h
+$(OBJDIR)/im_rgb2map.o: im_rgb2map.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_convert.h ../include/im_image.h \
+ ../include/im_counter.h
+$(OBJDIR)/im_colormode.o: im_colormode.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h
+$(OBJDIR)/im_format_gif.o: im_format_gif.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_lib.o: im_lib.cpp ../include/im_lib.h
+$(OBJDIR)/im_format_pnm.o: im_format_pnm.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_colorutil.o: im_colorutil.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h
+$(OBJDIR)/im_format_ico.o: im_format_ico.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_palette.o: im_palette.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_palette.h ../include/im_colorhsi.h
+$(OBJDIR)/im_convertbitmap.o: im_convertbitmap.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_complex.h \
+ ../include/im_math.h ../include/im_util.h ../include/im_image.h \
+ ../include/im_convert.h ../include/im_image.h ../include/im_counter.h
+$(OBJDIR)/im_format_led.o: im_format_led.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_counter.o: im_counter.cpp ../include/im_counter.h
+$(OBJDIR)/im_str.o: im_str.cpp ../include/im_util.h
+$(OBJDIR)/im_convertcolor.o: im_convertcolor.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_complex.h \
+ ../include/im_math.h ../include/im_util.h ../include/im_image.h \
+ ../include/im_convert.h ../include/im_image.h ../include/im_color.h \
+ ../include/im_counter.h
+$(OBJDIR)/im_fileraw.o: im_fileraw.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_raw.h ../include/im_format.h ../include/im_file.h \
+ ../include/im.h ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_raw.h
+$(OBJDIR)/im_format_krn.o: im_format_krn.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/im_file.o: im_file.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_format.h ../include/im_file.h ../include/im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h ../include/im_util.h \
+ ../include/im_attrib.h ../include/im_counter.h ../include/im_plus.h
+$(OBJDIR)/im_format_ras.o: im_format_ras.cpp ../include/im_format.h \
+ ../include/im_file.h ../include/im.h ../include/old_im.h \
+ ../include/im_attrib.h ../include/im_attrib_flat.h \
+ ../include/im_format_all.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_binfile.h ../include/im_util.h
+$(OBJDIR)/old_im.o: old_im.cpp ../include/old_im.h ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_counter.h
+$(OBJDIR)/im_sysfile_unix.o: im_sysfile_unix.cpp ../include/im_util.h \
+ ../include/im_binfile.h ../include/im_util.h
diff --git a/im/src/im.rc b/im/src/im.rc
new file mode 100755
index 0000000..990266a
--- /dev/null
+++ b/im/src/im.rc
@@ -0,0 +1,19 @@
+1 VERSIONINFO
+ FILEVERSION 3,4,2,0
+ PRODUCTVERSION 3,4,2,0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "www.tecgraf.puc-rio.br/im\0"
+ VALUE "CompanyName", "Tecgraf/PUC-Rio\0"
+ VALUE "FileDescription", "IM - Image Representation, Storage, Capture and Processing\0"
+ VALUE "FileVersion", "3.4.2\0"
+ VALUE "LegalCopyright", "Copyright © 1994-2009 Tecgraf, PUC-Rio.\0"
+ VALUE "OriginalFilename", "im.dll\0"
+ VALUE "ProductName", "IM for Windows\0"
+ VALUE "ProductVersion", "3.4.2\0"
+ END
+ END
+END
diff --git a/im/src/im_attrib.cpp b/im/src/im_attrib.cpp
new file mode 100755
index 0000000..10d4599
--- /dev/null
+++ b/im/src/im_attrib.cpp
@@ -0,0 +1,319 @@
+/** \file
+ * \brief Attributes Table
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_attrib.cpp,v 1.3 2009/08/22 04:31:04 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <assert.h>
+
+#include "im_attrib.h"
+#include "im_util.h"
+
+#define IM_DEFAULTSIZE 101
+#define IM_MULTIPLIER 31
+
+// Unique Hash index for a name
+static int iHashIndex(const char *name, int hash_size)
+{
+ unsigned short hash = 0;
+ const unsigned char *p_name = (const unsigned char*)name;
+
+ for(; *p_name; p_name++)
+ hash = hash*IM_MULTIPLIER + *p_name;
+
+ return hash % hash_size;
+}
+
+
+/*******************************************************************/
+
+
+class imAttribNode
+{
+public:
+ int data_type;
+ int count;
+ void* data;
+ char* name;
+
+ imAttribNode* next;
+
+ imAttribNode(const char* name, int _data_type, int _count, const void* _data, imAttribNode* next);
+ ~imAttribNode();
+};
+
+static char* utlStrDup(const char* str)
+{
+ int size;
+ char* new_str;
+
+ assert(str);
+
+ size = strlen(str) + 1;
+ new_str = (char*)malloc(size);
+ memcpy(new_str, str, size);
+
+ return new_str;
+}
+
+imAttribNode::imAttribNode(const char* name, int _data_type, int _count, const void* _data, imAttribNode* _next)
+{
+ if (_data_type == 0 && _count == -1) /* BYTE meaning a string */
+ _count = strlen((char*)_data)+1;
+
+ this->name = utlStrDup(name);
+ this->data_type = _data_type;
+ this->count = _count;
+ this->next = _next;
+
+ int size = _count * imDataTypeSize(_data_type);
+ this->data = malloc(size);
+ if (_data) memcpy(this->data, _data, size);
+ else memset(this->data, 0, size);
+}
+
+imAttribNode::~imAttribNode()
+{
+ free(this->name);
+ free(this->data);
+}
+
+
+/*******************************************************************/
+
+struct imAttribTablePrivate
+{
+ int count,
+ hash_size;
+ imAttribNode* *hash_table;
+};
+
+imAttribTablePrivate* imAttribTableCreate(int hash_size)
+{
+ imAttribTablePrivate* ptable = (imAttribTablePrivate*)malloc(sizeof(imAttribTablePrivate));
+ ptable->count = 0;
+ ptable->hash_size = (hash_size == 0)? IM_DEFAULTSIZE: hash_size;
+ ptable->hash_table = (imAttribNode**)malloc(ptable->hash_size*sizeof(imAttribNode*));
+ memset(ptable->hash_table, 0, ptable->hash_size*sizeof(imAttribNode*));
+ return ptable;
+}
+
+imAttribTablePrivate* imAttribArrayCreate(int count)
+{
+ imAttribTablePrivate* ptable = (imAttribTablePrivate*)malloc(sizeof(imAttribTablePrivate));
+ ptable->hash_size = ptable->count = count;
+ ptable->hash_table = (imAttribNode**)malloc(ptable->count*sizeof(imAttribNode*));
+ memset(ptable->hash_table, 0, ptable->hash_size*sizeof(imAttribNode*));
+ return ptable;
+}
+
+void imAttribTableDestroy(imAttribTablePrivate* ptable)
+{
+ imAttribTableRemoveAll(ptable);
+ free(ptable->hash_table);
+ free(ptable);
+}
+
+int imAttribTableCount(imAttribTablePrivate* ptable)
+{
+ return ptable->count;
+}
+
+void imAttribTableRemoveAll(imAttribTablePrivate* ptable)
+{
+ if (ptable->count == 0) return;
+
+ int n = 0;
+ for(int i = 0; i < ptable->hash_size; i++)
+ {
+ imAttribNode* cur_node = ptable->hash_table[i];
+ while (cur_node)
+ {
+ imAttribNode* next_node = cur_node->next;
+ delete cur_node;
+ cur_node = next_node;
+ n++;
+ }
+
+ ptable->hash_table[i] = NULL;
+
+ if (n == ptable->count)
+ break;
+ }
+
+ ptable->count = 0;
+}
+
+void imAttribTableSet(imAttribTablePrivate* ptable, const char* name, int data_type, int count, const void* data)
+{
+ assert(name);
+
+ int index = iHashIndex(name, ptable->hash_size);
+ imAttribNode* first_node = ptable->hash_table[index];
+
+ // The name already exists ?
+ imAttribNode* cur_node = first_node;
+ imAttribNode* prev_node = NULL;
+ while (cur_node)
+ {
+ if (imStrEqual(cur_node->name, name))
+ {
+ // Found, replace current node.
+ imAttribNode* new_node = new imAttribNode(name, data_type, count, data, cur_node->next);
+
+ // Is first node ?
+ if (cur_node == first_node)
+ ptable->hash_table[index] = new_node;
+ else
+ prev_node->next = new_node;
+
+ delete cur_node;
+ return;
+ }
+
+ prev_node = cur_node;
+ cur_node = cur_node->next;
+ }
+
+ // Not found, the new item goes first.
+ cur_node = new imAttribNode(name, data_type, count, data, first_node);
+ ptable->hash_table[index] = cur_node;
+ ptable->count++;
+}
+
+void imAttribTableUnSet(imAttribTablePrivate* ptable, const char *name)
+{
+ assert(name);
+
+ if (ptable->count == 0) return;
+
+ int index = iHashIndex(name, ptable->hash_size);
+
+ imAttribNode* cur_node = ptable->hash_table[index];
+ imAttribNode* prev_node = cur_node;
+ while (cur_node)
+ {
+ if (imStrEqual(cur_node->name, name))
+ {
+ // Is first node ?
+ if (cur_node == prev_node)
+ ptable->hash_table[index] = cur_node->next;
+ else
+ prev_node->next = cur_node->next;
+
+ delete cur_node;
+ ptable->count--;
+ return;
+ }
+
+ prev_node = cur_node;
+ cur_node = cur_node->next;
+ }
+}
+
+const void* imAttribTableGet(const imAttribTablePrivate* ptable, const char *name, int *data_type, int *count)
+{
+ assert(name);
+
+ if (ptable->count == 0) return NULL;
+
+ int index = iHashIndex(name, ptable->hash_size);
+
+ imAttribNode* cur_node = ptable->hash_table[index];
+ while (cur_node)
+ {
+ if (imStrEqual(cur_node->name, name))
+ {
+ if (data_type) *data_type = cur_node->data_type;
+ if (count) *count = cur_node->count;
+ return cur_node->data;
+ }
+
+ cur_node = cur_node->next;
+ }
+
+ return NULL;
+}
+
+void imAttribArraySet(imAttribTablePrivate* ptable, int index, const char* name, int data_type, int count, const void* data)
+{
+ assert(name);
+ assert(index < ptable->count);
+
+ if (index >= ptable->count) return;
+
+ imAttribNode* node = ptable->hash_table[index];
+ if (node) delete node;
+
+ ptable->hash_table[index] = new imAttribNode(name, data_type, count, data, NULL);
+}
+
+const void* imAttribArrayGet(const imAttribTablePrivate* ptable, int index, char *name, int *data_type, int *count)
+{
+ if (ptable->count == 0) return NULL;
+
+ imAttribNode* node = ptable->hash_table[index];
+ if (node)
+ {
+ if (name) strcpy(name, node->name);
+ if (data_type) *data_type = node->data_type;
+ if (count) *count = node->count;
+ return node->data;
+ }
+
+ return NULL;
+}
+
+void imAttribTableForEach(const imAttribTablePrivate* ptable, void* user_data, imAttribTableCallback attrib_func)
+{
+ assert(attrib_func);
+
+ if (ptable->count == 0) return;
+
+ int index = 0;
+ for(int i = 0; i < ptable->hash_size; i++)
+ {
+ imAttribNode* cur_node = ptable->hash_table[i];
+ while (cur_node)
+ {
+ if (!attrib_func(user_data, index, cur_node->name, cur_node->data_type, cur_node->count, cur_node->data))
+ return;
+
+ index++;
+ cur_node = cur_node->next;
+ }
+
+ if (index == ptable->count)
+ return;
+ }
+}
+
+static int iCopyFunc(void* user_data, int index, const char* name, int data_type, int count, const void* data)
+{
+ (void)index;
+ imAttribTablePrivate* ptable = (imAttribTablePrivate*)user_data;
+ imAttribTableSet(ptable, name, data_type, count, data);
+ return 1;
+}
+
+void imAttribTableCopyFrom(imAttribTablePrivate* ptable_dst, const imAttribTablePrivate* ptable_src)
+{
+ imAttribTableForEach(ptable_src, (void*)ptable_dst, iCopyFunc);
+}
+
+static int iCopyArrayFunc(void* user_data, int index, const char* name, int data_type, int count, const void* data)
+{
+ (void)index;
+ imAttribTablePrivate* ptable = (imAttribTablePrivate*)user_data;
+ imAttribArraySet(ptable, index, name, data_type, count, data);
+ return 1;
+}
+
+void imAttribArrayCopyFrom(imAttribTablePrivate* ptable_dst, const imAttribTablePrivate* ptable_src)
+{
+ imAttribTableForEach(ptable_src, (void*)ptable_dst, iCopyArrayFunc);
+}
diff --git a/im/src/im_bin.cpp b/im/src/im_bin.cpp
new file mode 100755
index 0000000..de279b5
--- /dev/null
+++ b/im/src/im_bin.cpp
@@ -0,0 +1,111 @@
+/** \file
+ * \brief Binary Data Utilities
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_bin.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include <assert.h>
+
+#include "im_util.h"
+
+
+int imBinCPUByteOrder(void)
+{
+ static int CPUByteOrder = -1;
+
+ if (CPUByteOrder == -1)
+ {
+ unsigned short w = 0x0001;
+ unsigned char* b = (unsigned char*)&w;
+ CPUByteOrder = (b[0] == 0x01)? IM_LITTLEENDIAN: IM_BIGENDIAN;
+ }
+
+ return CPUByteOrder;
+}
+
+void imBinSwapBytes(void *data, int count, int size)
+{
+ switch(size)
+ {
+ case 2:
+ imBinSwapBytes2(data, count);
+ break;
+ case 4:
+ imBinSwapBytes4(data, count);
+ break;
+ case 8:
+ imBinSwapBytes8(data, count);
+ break;
+ }
+}
+
+void imBinSwapBytes2(void *data, int count)
+{
+ assert(data);
+
+ unsigned char lTemp;
+ unsigned char *values = (unsigned char *)data;
+
+ while (count-- != 0)
+ {
+ lTemp = values[1];
+ values[1] = values[0];
+ values[0] = lTemp;
+
+ values += 2;
+ }
+}
+
+void imBinSwapBytes4(void *data, int count)
+{
+ assert(data);
+
+ unsigned char lTemp;
+ unsigned char *values = (unsigned char *)data;
+
+ while (count-- != 0)
+ {
+ lTemp = values[3];
+ values[3] = values[0];
+ values[0] = lTemp;
+
+ lTemp = values[2];
+ values[2] = values[1];
+ values[1] = lTemp;
+
+ values += 4;
+ }
+}
+
+void imBinSwapBytes8(void *data, int count)
+{
+ assert(data);
+
+ unsigned char lTemp;
+ unsigned char *values = (unsigned char *)data;
+
+ assert(values);
+
+ while (count-- != 0)
+ {
+ lTemp = values[7];
+ values[7] = values[0];
+ values[0] = lTemp;
+
+ lTemp = values[6];
+ values[6] = values[1];
+ values[1] = lTemp;
+
+ lTemp = values[5];
+ values[5] = values[2];
+ values[2] = lTemp;
+
+ lTemp = values[4];
+ values[4] = values[3];
+ values[3] = lTemp;
+
+ values += 8;
+ }
+}
+
diff --git a/im/src/im_binfile.cpp b/im/src/im_binfile.cpp
new file mode 100755
index 0000000..7171032
--- /dev/null
+++ b/im/src/im_binfile.cpp
@@ -0,0 +1,710 @@
+/** \file
+ * \brief Binary File Access
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_binfile.cpp,v 1.2 2009/10/01 14:15:47 scuri Exp $
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include "im_util.h"
+#include "im_binfile.h"
+
+
+/**************************************************
+ imBinMemoryFile
+***************************************************/
+
+class imBinMemoryFile: public imBinFileBase
+{
+protected:
+ unsigned long CurrentSize, BufferSize;
+ unsigned char* Buffer, *CurPos;
+ int Error;
+ float Reallocate;
+ imBinMemoryFileName* file_name;
+
+ unsigned long ReadBuf(void* pValues, unsigned long pSize);
+ unsigned long WriteBuf(void* pValues, unsigned long pSize);
+
+public:
+ void Open(const char* pFileName);
+ void New(const char* pFileName);
+ void Close() {} // Does nothing, the memory belongs to the user
+
+ unsigned long FileSize();
+ int HasError() const;
+ void SeekTo(unsigned long pOffset);
+ void SeekOffset(long pOffset);
+ void SeekFrom(long pOffset);
+ unsigned long Tell() const;
+ int EndOfFile() const;
+};
+
+static imBinFileBase* iBinMemoryFileNewFunc()
+{
+ return new imBinMemoryFile();
+}
+
+void imBinMemoryRelease(unsigned char *buffer)
+{
+ free(buffer);
+}
+
+void imBinMemoryFile::Open(const char* pFileName)
+{
+ this->file_name = (imBinMemoryFileName*)pFileName;
+
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 0;
+
+ assert(this->file_name->size);
+
+ this->Buffer = this->file_name->buffer;
+ this->BufferSize = this->file_name->size;
+ this->Reallocate = this->file_name->reallocate;
+ this->CurrentSize = this->BufferSize;
+ this->CurPos = this->Buffer;
+ this->Error = 0;
+}
+
+void imBinMemoryFile::New(const char* pFileName)
+{
+ this->file_name = (imBinMemoryFileName*)pFileName;
+
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 1;
+
+ assert(this->file_name->size);
+
+ this->Buffer = this->file_name->buffer;
+ this->BufferSize = this->file_name->size;
+ this->Reallocate = this->file_name->reallocate;
+ this->CurrentSize = 0;
+
+ if (!this->Buffer)
+ {
+ this->Buffer = (unsigned char*)malloc(this->BufferSize);
+ this->file_name->buffer = this->Buffer;
+ }
+
+ this->CurPos = this->Buffer;
+ this->Error = 0;
+}
+
+unsigned long imBinMemoryFile::ReadBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->Buffer);
+
+ unsigned long lOffset = this->CurPos - this->Buffer;
+
+ this->Error = 0;
+ if (lOffset + pSize > this->CurrentSize)
+ {
+ this->Error = 1;
+ pSize = this->CurrentSize - lOffset;
+ }
+
+ if (pSize)
+ {
+ memcpy(pValues, this->CurPos, pSize);
+ this->CurPos += pSize;
+ }
+
+ return pSize;
+}
+
+unsigned long imBinMemoryFile::WriteBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->Buffer);
+
+ unsigned long lOffset = this->CurPos - this->Buffer;
+
+ this->Error = 0;
+ if (lOffset + pSize > this->BufferSize)
+ {
+ if (this->Reallocate != 0.0)
+ {
+ unsigned long nSize = this->BufferSize;
+ while (lOffset + pSize > nSize)
+ nSize += (unsigned long)(this->Reallocate*(float)this->BufferSize);
+
+ this->Buffer = (unsigned char*)realloc(this->Buffer, nSize);
+
+ if (this->Buffer)
+ {
+ this->BufferSize = nSize;
+ this->file_name->buffer = this->Buffer;
+ this->file_name->size = this->BufferSize;
+ }
+ else
+ {
+ this->Buffer = this->file_name->buffer;
+ this->Error = 1;
+ pSize = this->BufferSize - lOffset;
+ }
+
+ this->CurPos = this->Buffer + lOffset;
+ }
+ else
+ {
+ this->Error = 1;
+ pSize = this->BufferSize - lOffset;
+ }
+ }
+
+ memcpy(this->CurPos, pValues, pSize);
+
+ if (lOffset + pSize > this->CurrentSize)
+ this->CurrentSize = lOffset + pSize;
+
+ this->CurPos += pSize;
+
+ return pSize;
+}
+
+unsigned long imBinMemoryFile::FileSize()
+{
+ assert(this->Buffer);
+ return this->CurrentSize;
+}
+
+int imBinMemoryFile::HasError() const
+{
+ if (!this->Buffer) return 1;
+ return this->Error;
+}
+
+void imBinMemoryFile::SeekTo(unsigned long pOffset)
+{
+ assert(this->Buffer);
+
+ this->Error = 0;
+ if (pOffset > this->BufferSize)
+ {
+ this->Error = 1;
+ return;
+ }
+
+ this->CurPos = this->Buffer + pOffset;
+
+ /* update size if we seek after EOF */
+ if (pOffset > this->CurrentSize)
+ this->CurrentSize = pOffset;
+}
+
+void imBinMemoryFile::SeekFrom(long pOffset)
+{
+ assert(this->Buffer);
+
+ /* remember that offset is usually a negative value in this case */
+
+ this->Error = 0;
+ if (this->CurrentSize + pOffset > this->BufferSize ||
+ (long)this->CurrentSize + pOffset < 0)
+ {
+ this->Error = 1;
+ return;
+ }
+
+ this->CurPos = this->Buffer + this->CurrentSize + pOffset;
+
+ /* update size if we seek after EOF */
+ if (pOffset > 0)
+ this->CurrentSize = this->CurrentSize + pOffset;
+}
+
+void imBinMemoryFile::SeekOffset(long pOffset)
+{
+ assert(this->Buffer);
+ long lOffset = this->CurPos - this->Buffer;
+
+ this->Error = 0;
+ if (lOffset + pOffset < 0 || lOffset + pOffset > (long)this->BufferSize)
+ {
+ this->Error = 1;
+ return;
+ }
+
+ this->CurPos += pOffset;
+
+ /* update size if we seek after EOF */
+ if (lOffset + pOffset > (long)this->CurrentSize)
+ this->CurrentSize = lOffset + pOffset;
+}
+
+unsigned long imBinMemoryFile::Tell() const
+{
+ assert(this->Buffer);
+ unsigned long lOffset = this->CurPos - this->Buffer;
+ return lOffset;
+}
+
+int imBinMemoryFile::EndOfFile() const
+{
+ assert(this->Buffer);
+ unsigned long lOffset = this->CurPos - this->Buffer;
+ return lOffset == this->CurrentSize? 1: 0;
+}
+
+/**************************************************
+ imBinSubFile
+**************************************************/
+
+static imBinFileBase* iBinFileBaseHandle(const char* pFileName);
+
+class imBinSubFile: public imBinFileBase
+{
+protected:
+ imBinFileBase* FileHandle;
+ unsigned long StartOffset;
+
+ unsigned long ReadBuf(void* pValues, unsigned long pSize);
+ unsigned long WriteBuf(void* pValues, unsigned long pSize);
+
+public:
+ void Open(const char* pFileName);
+ void New(const char* pFileName);
+ void Close() {} // Does nothing, the file should be close by the parent file.
+
+ unsigned long FileSize();
+ int HasError() const;
+ void SeekTo(unsigned long pOffset);
+ void SeekOffset(long pOffset);
+ void SeekFrom(long pOffset);
+ unsigned long Tell() const;
+ int EndOfFile() const;
+};
+
+static imBinFileBase* iBinSubFileNewFunc()
+{
+ return new imBinSubFile();
+}
+
+void imBinSubFile::Open(const char* pFileName)
+{
+ this->FileHandle = iBinFileBaseHandle(pFileName);
+ this->FileByteOrder = this->FileByteOrder;
+ this->IsNew = 0;
+
+ StartOffset = this->FileHandle->Tell();
+}
+
+void imBinSubFile::New(const char* pFileName)
+{
+ this->FileHandle = iBinFileBaseHandle(pFileName);
+ this->FileByteOrder = this->FileByteOrder;
+ this->IsNew = 1;
+
+ StartOffset = this->FileHandle->Tell();
+}
+
+unsigned long imBinSubFile::FileSize()
+{
+ assert(this->FileHandle);
+ return this->FileHandle->FileSize();
+}
+
+unsigned long imBinSubFile::ReadBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle);
+ return this->FileHandle->ReadBuf(pValues, pSize);
+}
+
+unsigned long imBinSubFile::WriteBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle);
+ return this->FileHandle->WriteBuf(pValues, pSize);
+}
+
+int imBinSubFile::HasError() const
+{
+ assert(this->FileHandle);
+ return this->FileHandle->HasError();
+}
+
+void imBinSubFile::SeekTo(unsigned long pOffset)
+{
+ assert(this->FileHandle);
+ this->FileHandle->SeekTo(StartOffset + pOffset);
+}
+
+void imBinSubFile::SeekOffset(long pOffset)
+{
+ assert(this->FileHandle);
+ this->FileHandle->SeekOffset(pOffset);
+}
+
+void imBinSubFile::SeekFrom(long pOffset)
+{
+ assert(this->FileHandle);
+ this->FileHandle->SeekFrom(pOffset);
+}
+
+unsigned long imBinSubFile::Tell() const
+{
+ assert(this->FileHandle);
+ return this->FileHandle->Tell() - StartOffset;
+}
+
+int imBinSubFile::EndOfFile() const
+{
+ assert(this->FileHandle);
+ return this->FileHandle->EndOfFile();
+}
+
+/**************************************************
+ imBinStreamFile
+**************************************************/
+
+class imBinStreamFile: public imBinFileBase
+{
+protected:
+ FILE* FileHandle;
+
+ unsigned long ReadBuf(void* pValues, unsigned long pSize);
+ unsigned long WriteBuf(void* pValues, unsigned long pSize);
+
+public:
+ void Open(const char* pFileName);
+ void New(const char* pFileName);
+ void Close();
+
+ unsigned long FileSize();
+ int HasError() const;
+ void SeekTo(unsigned long pOffset);
+ void SeekOffset(long pOffset);
+ void SeekFrom(long pOffset);
+ unsigned long Tell() const;
+ int EndOfFile() const;
+};
+
+static imBinFileBase* iBinStreamFileNewFunc()
+{
+ return new imBinStreamFile();
+}
+
+void imBinStreamFile::Open(const char* pFileName)
+{
+ this->FileHandle = fopen(pFileName, "rb");
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 0;
+}
+
+void imBinStreamFile::New(const char* pFileName)
+{
+ this->FileHandle = fopen(pFileName, "wb");
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 1;
+}
+
+void imBinStreamFile::Close()
+{
+ if (this->FileHandle) fclose(this->FileHandle);
+}
+
+unsigned long imBinStreamFile::FileSize()
+{
+ assert(this->FileHandle);
+ unsigned long lCurrentPosition = ftell(this->FileHandle);
+ fseek(this->FileHandle, 0L, SEEK_END);
+ unsigned long lSize = ftell(this->FileHandle);
+ fseek(this->FileHandle, lCurrentPosition, SEEK_SET);
+ return lSize;
+}
+
+unsigned long imBinStreamFile::ReadBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle);
+ return fread(pValues, 1, pSize, this->FileHandle);
+}
+
+unsigned long imBinStreamFile::WriteBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle);
+ return fwrite(pValues, 1, pSize, this->FileHandle);
+}
+
+int imBinStreamFile::HasError() const
+{
+ if (!this->FileHandle) return 1;
+ return ferror(this->FileHandle) == 0? 0: 1;
+}
+
+void imBinStreamFile::SeekTo(unsigned long pOffset)
+{
+ assert(this->FileHandle);
+ fseek(this->FileHandle, pOffset, SEEK_SET);
+}
+
+void imBinStreamFile::SeekOffset(long pOffset)
+{
+ assert(this->FileHandle);
+ fseek(this->FileHandle, pOffset, SEEK_CUR);
+}
+
+void imBinStreamFile::SeekFrom(long pOffset)
+{
+ assert(this->FileHandle);
+ fseek(this->FileHandle, pOffset, SEEK_END);
+}
+
+unsigned long imBinStreamFile::Tell() const
+{
+ assert(this->FileHandle);
+ return ftell(this->FileHandle);
+}
+
+int imBinStreamFile::EndOfFile() const
+{
+ assert(this->FileHandle);
+ return feof(this->FileHandle) == 0? 0: 1;
+}
+
+/**************************************************
+ NewFuncModules
+**************************************************/
+
+/* implemented in "im_sysfile*.cpp" */
+imBinFileBase* iBinSystemFileNewFunc();
+imBinFileBase* iBinSystemFileHandleNewFunc();
+
+#define MAX_MODULES 10
+
+static imBinFileNewFunc iBinFileModule[MAX_MODULES] =
+{
+ iBinSystemFileNewFunc,
+ iBinStreamFileNewFunc,
+ iBinMemoryFileNewFunc,
+ iBinSubFileNewFunc,
+ iBinSystemFileHandleNewFunc
+};
+static int iBinFileModuleCount = 5;
+static int iBinFileModuleCurrent = 0; // default module is the first
+
+int imBinFileSetCurrentModule(int pModule)
+{
+ int old_module = iBinFileModuleCurrent;
+
+ if (pModule >= iBinFileModuleCount)
+ return -1;
+
+ iBinFileModuleCurrent = pModule;
+
+ return old_module;
+}
+
+int imBinFileRegisterModule(imBinFileNewFunc pNewFunc)
+{
+ if (iBinFileModuleCount == MAX_MODULES) return -1;
+ int id = iBinFileModuleCount;
+ iBinFileModule[id] = pNewFunc;
+ iBinFileModuleCount++;
+ return id;
+}
+
+/**************************************************
+ imBinFile
+**************************************************/
+
+struct _imBinFile
+{
+ imBinFileBase* binfile;
+};
+
+imBinFile* imBinFileOpen(const char* pFileName)
+{
+ assert(pFileName);
+
+ assert(iBinFileModuleCurrent < iBinFileModuleCount);
+ assert(iBinFileModuleCurrent < MAX_MODULES);
+
+ imBinFileNewFunc NewFunc = iBinFileModule[iBinFileModuleCurrent];
+ imBinFileBase* binfile = NewFunc();
+
+ binfile->Open(pFileName);
+ if (binfile->HasError())
+ {
+ delete binfile;
+ return NULL;
+ }
+
+ imBinFile* bfile = new imBinFile;
+ bfile->binfile = binfile;
+
+ return bfile;
+}
+
+imBinFile* imBinFileNew(const char* pFileName)
+{
+ assert(pFileName);
+
+ imBinFileNewFunc NewFunc = iBinFileModule[iBinFileModuleCurrent];
+ imBinFileBase* binfile = NewFunc();
+
+ binfile->New(pFileName);
+ if (binfile->HasError())
+ {
+ delete binfile;
+ return NULL;
+ }
+
+ imBinFile* bfile = new imBinFile;
+ bfile->binfile = binfile;
+
+ return bfile;
+}
+
+void imBinFileClose(imBinFile* bfile)
+{
+ assert(bfile);
+ bfile->binfile->Close();
+ delete bfile->binfile;
+ delete bfile;
+}
+
+int imBinFileByteOrder(imBinFile* bfile, int pByteOrder)
+{
+ assert(bfile);
+ return bfile->binfile->InitByteOrder(pByteOrder);
+}
+
+int imBinFileError(imBinFile* bfile)
+{
+ assert(bfile);
+ return bfile->binfile->HasError();
+}
+
+unsigned long imBinFileSize(imBinFile* bfile)
+{
+ assert(bfile);
+ return bfile->binfile->FileSize();
+}
+
+unsigned long imBinFileRead(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf)
+{
+ assert(bfile);
+ return bfile->binfile->Read(pValues, pCount, pSizeOf);
+}
+
+unsigned long imBinFileWrite(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf)
+{
+ assert(bfile);
+ return bfile->binfile->Write(pValues, pCount, pSizeOf);
+}
+
+void imBinFileSeekTo(imBinFile* bfile, unsigned long pOffset)
+{
+ assert(bfile);
+ bfile->binfile->SeekTo(pOffset);
+}
+
+void imBinFileSeekOffset(imBinFile* bfile, long pOffset)
+{
+ assert(bfile);
+ bfile->binfile->SeekOffset(pOffset);
+}
+
+void imBinFileSeekFrom(imBinFile* bfile, long pOffset)
+{
+ assert(bfile);
+ bfile->binfile->SeekFrom(pOffset);
+}
+
+unsigned long imBinFileTell(imBinFile* bfile)
+{
+ assert(bfile);
+ return bfile->binfile->Tell();
+}
+
+int imBinFileEndOfFile(imBinFile* bfile)
+{
+ assert(bfile);
+ return bfile->binfile->EndOfFile();
+}
+
+unsigned long imBinFilePrintf(imBinFile* bfile, char *format, ...)
+{
+ va_list arglist;
+ va_start(arglist, format);
+ char buffer[4096];
+ int size = vsprintf(buffer, format, arglist);
+ return imBinFileWrite(bfile, buffer, size, 1);
+}
+
+int imBinFileReadInteger(imBinFile* handle, int *value)
+{
+ int i = 0, found = 0;
+ char buffer[11], c;
+
+ while (!found)
+ {
+ imBinFileRead(handle, &c, 1, 1);
+
+ /* if it's an integer, increments the number of characters read */
+ if ((c >= '0' && c <= '9') || (c == '-'))
+ {
+ buffer[i] = c;
+ i++;
+ }
+ else
+ {
+ /* if it's not, and we read some characters, convert them to an integer */
+ if (i > 0)
+ {
+ buffer[i] = 0;
+ *value = atoi(buffer);
+ found = 1;
+ }
+ }
+
+ if (imBinFileError(handle) || i > 10)
+ return 0;
+ }
+
+ return 1;
+}
+
+int imBinFileReadFloat(imBinFile* handle, float *value)
+{
+ int i = 0, found = 0;
+ char buffer[17], c;
+
+ while (!found)
+ {
+ imBinFileRead(handle, &c, 1, 1);
+
+ /* if it's a floating point number, increments the number of characters read */
+ if ((c >= '0' && c <= '9') || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E')
+ {
+ buffer[i] = c;
+ i++;
+ }
+ else
+ {
+ /* if it's not, and we read some characters convert them to an integer */
+ if (i > 0)
+ {
+ buffer[i] = 0;
+ *value = (float)atof(buffer);
+ found = 1;
+ }
+ }
+
+ if (imBinFileError(handle) || i > 16)
+ return 0;
+ }
+
+ return 1;
+}
+
+static imBinFileBase* iBinFileBaseHandle(const char* pFileName)
+{
+ imBinFile* bfile = (imBinFile*)pFileName;
+ return (imBinFileBase*)bfile->binfile;
+}
diff --git a/im/src/im_capture.def b/im/src/im_capture.def
new file mode 100755
index 0000000..6b44ac3
--- /dev/null
+++ b/im/src/im_capture.def
@@ -0,0 +1,27 @@
+EXPORTS
+ imVideoCaptureDeviceCount
+ imVideoCaptureDeviceDesc
+ imVideoCaptureReloadDevices
+ imVideoCaptureCreate
+ imVideoCaptureDestroy
+ imVideoCaptureConnect
+ imVideoCaptureDisconnect
+ imVideoCaptureShowDialog
+ imVideoCaptureDialogCount
+ imVideoCaptureDialogDesc
+ imVideoCaptureGetImageSize
+ imVideoCaptureSetImageSize
+ imVideoCaptureFrame
+ imVideoCaptureOneFrame
+ imVideoCaptureLive
+ imVideoCaptureResetAttribute
+ imVideoCaptureGetAttribute
+ imVideoCaptureSetAttribute
+ imVideoCaptureGetAttributeList
+ imVideoCaptureFormatCount
+ imVideoCaptureGetFormat
+ imVideoCaptureSetFormat
+ imVideoCaptureSetInOut
+ imVideoCaptureDeviceExDesc
+ imVideoCaptureDevicePath
+ imVideoCaptureDeviceVendorInfo
diff --git a/im/src/im_capture.mak b/im/src/im_capture.mak
new file mode 100755
index 0000000..8f10bc7
--- /dev/null
+++ b/im/src/im_capture.mak
@@ -0,0 +1,73 @@
+PROJNAME = im
+LIBNAME = im_capture
+OPT = YES
+
+INCLUDES = ../include
+
+# New Direct X does not includes Direct Show
+# Direct Show is included in latest Platform SDK, but depends on Direct X...
+DXSDK = d:/lng/dxsdk
+WINSDK = d:/lng/winsdk
+
+ifeq ($(TEC_UNAME), vc6)
+ #Use old Direct X with Direct Show
+ #But do NOT use the VC6 strmiids.lib
+ PLATSDK = d:/lng/vc7/PlatformSDK
+endif
+
+ifeq ($(TEC_UNAME), dll)
+ #Use old Direct X with Direct Show
+ PLATSDK = d:/lng/vc7/PlatformSDK
+ LDIR = ../lib/$(TEC_UNAME)
+endif
+
+ifeq ($(TEC_UNAME), vc8)
+ INCLUDES += $(WINSDK)/include
+ LDIR = $(WINSDK)/lib
+endif
+
+ifeq ($(TEC_UNAME), dll8)
+ INCLUDES += $(WINSDK)/include
+ LDIR = $(WINSDK)/lib
+endif
+
+ifeq ($(TEC_UNAME), vc8_64)
+ INCLUDES += $(WINSDK)/include
+ LDIR = $(WINSDK)/lib/amd64
+endif
+
+ifeq ($(TEC_UNAME), dll8_64)
+ INCLUDES += $(WINSDK)/include
+ LDIR = $(WINSDK)/lib/amd64
+endif
+
+ifneq ($(findstring Win, $(TEC_SYSNAME)), )
+ INCLUDES += $(DXSDK)/include
+ SRC = im_capture_dx.cpp
+endif
+
+#ifneq ($(findstring Linux, $(TEC_UNAME)), )
+# SRC = im_capture_v4l.cpp
+#endif
+
+LIBS = strmiids
+
+mingw3-dll:
+ @echo Importing MingW stub library
+ @cd ../lib/dll
+ @dlltool -d im_capture.def -D im_capture.dll -l ../lib/mingw3/libim_capture.a
+ @cd ../src
+
+mingw4-dll:
+ @echo Importing MingW stub library
+ @cd ../lib/dll
+ @dlltool -d im_capture.def -D im_capture.dll -l ../lib/mingw4/libim_capture.a
+ @cd ../src
+
+bc56-dll:
+ @echo Importing Bcc stub library
+ @d:/lng/cbuilderx/bin/implib -a ../lib/bc56/im_capture.lib ../lib/dll/im_capture.dll
+
+#owc1-dll:
+# @wlib -b -c -n -q -fo -io ../lib/owc1/im_capture.lib @im_capture.wlib
+# TEST @wlib -b -c -n -q -fo -io ../lib/owc1/im_capture.lib +../lib/dll/im_capture.dll
diff --git a/im/src/im_capture.wlib b/im/src/im_capture.wlib
new file mode 100644
index 0000000..7dca75e
--- /dev/null
+++ b/im/src/im_capture.wlib
@@ -0,0 +1,22 @@
+++imVideoCaptureDeviceCount.im_capture._imVideoCaptureDeviceCount
+++imVideoCaptureDeviceDesc.im_capture._imVideoCaptureDeviceDesc
+++imVideoCaptureReloadDevices.im_capture._imVideoCaptureReloadDevices
+++imVideoCaptureCreate.im_capture._imVideoCaptureCreate
+++imVideoCaptureDestroy.im_capture._imVideoCaptureDestroy
+++imVideoCaptureConnect.im_capture._imVideoCaptureConnect
+++imVideoCaptureDisconnect.im_capture._imVideoCaptureDisconnect
+++imVideoCaptureShowDialog.im_capture._imVideoCaptureShowDialog
+++imVideoCaptureDialogCount.im_capture._imVideoCaptureDialogCount
+++imVideoCaptureDialogDesc.im_capture._imVideoCaptureDialogDesc
+++imVideoCaptureGetImageSize.im_capture._imVideoCaptureGetImageSize
+++imVideoCaptureSetImageSize.im_capture._imVideoCaptureSetImageSize
+++imVideoCaptureFrame.im_capture._imVideoCaptureFrame
+++imVideoCaptureOneFrame.im_capture._imVideoCaptureOneFrame
+++imVideoCaptureLive.im_capture._imVideoCaptureLive
+++imVideoCaptureResetAttribute.im_capture._imVideoCaptureResetAttribute
+++imVideoCaptureGetAttribute.im_capture._imVideoCaptureGetAttribute
+++imVideoCaptureSetAttribute.im_capture._imVideoCaptureSetAttribute
+++imVideoCaptureGetAttributeList.im_capture._imVideoCaptureGetAttributeList
+++imVideoCaptureFormatCount.im_capture._imVideoCaptureFormatCount
+++imVideoCaptureGetFormat.im_capture._imVideoCaptureGetFormat
+++imVideoCaptureSetFormat.im_capture._imVideoCaptureSetFormat
diff --git a/im/src/im_capture_dx.cpp b/im/src/im_capture_dx.cpp
new file mode 100755
index 0000000..cb4749b
--- /dev/null
+++ b/im/src/im_capture_dx.cpp
@@ -0,0 +1,2255 @@
+/** \file
+ * \brief Video Capture Using Direct Show 9
+ *
+ * See Copyright Notice in im.h
+ * $Id: im_capture_dx.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+/*
+ The Direct Show Graph is composed by 3 components:
+ capture source, sample grabber and null renderer.
+
+ Filters are connected:
+ capture_filter(out)->(int)grabber_filter(out)->(in)null_filter
+
+ But when the graph is rendered other transform filters
+ can be inserted to connect the capture and the grabber.
+
+ We do not use MFC, ATL and the Direct Show Base Classes.
+ This module only needs the library "strmiids.lib".
+ If the extra error functions were used, you will need to link with "quartz.lib" or "dxerr9.lib".
+
+ We use the buffer of the ISampleGrabber. But this can not be done in a user callback,
+ so we leave the grab loop for the application, it can also be done in the idle function.
+
+ If you use the idle function for the grab loop, then WDM Source Dialog will interrupt the "live" mode.
+ Just because it is a modal dialog and it does not use the application message loop.
+ It can be solved if the grab loop is implemented using a timer.
+
+ Since there is no gray format, bpp is always 24bpp.
+*/
+
+#define _WIN32_WINNT 0x0500 // Because of TryEnterCriticalSection
+
+#include <dshow.h>
+#include <qedit.h>
+
+#include <memory.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <im.h>
+#include <im_util.h>
+
+#include "im_capture.h"
+
+#define VC_CAMERADELAY 200 // This vary from camera to camera, so we use a reasonable value and hope it will work for all.
+#define VC_MAXVIDDEVICES 30 // Maximum number of devices to list
+
+//#define VC_REGISTER_FILTERGRAPH // Use this to allow GraphEdit to spy the graph
+//#define VC_INCLUDE_VFW_DEVICES // Use this to allow old video for windows devices
+//#define VC_PRINT_ERROR_MESSAGES // Use this to display a system custom error message
+
+#if defined(_DEBUG) | defined(DEBUG)
+#define VC_REGISTER_FILTERGRAPH
+#define VC_PRINT_ERROR_MESSAGES
+#endif
+
+
+/**************************************************************************
+ imTrackingGrabberCB
+***************************************************************************/
+
+// This is better than using the sample grabber internal buffer
+// because we have a more precise control of the data flow.
+
+class imTrackingGrabberCB: public ISampleGrabberCB
+{
+public:
+ imTrackingGrabberCB();
+ ~imTrackingGrabberCB();
+
+ STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample);
+ STDMETHODIMP BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen) {return E_NOTIMPL;}
+ STDMETHODIMP_(ULONG) AddRef() {return 2;}
+ STDMETHODIMP_(ULONG) Release() {return 1;}
+ STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
+
+ void SetImageSize(int width, int height);
+ int GetImage(unsigned char* data, int color_mode, int timeout);
+
+protected:
+ int m_Width, m_Height;
+ bool m_newImageFlag;
+ unsigned char *m_ImageData;
+ CRITICAL_SECTION m_sect;
+ HANDLE m_imageReady;
+};
+
+imTrackingGrabberCB::imTrackingGrabberCB()
+{
+ InitializeCriticalSection(&m_sect);
+ m_newImageFlag = 0;
+ m_ImageData = NULL;
+ m_imageReady = CreateEvent(NULL, FALSE, TRUE, NULL);
+}
+
+imTrackingGrabberCB::~imTrackingGrabberCB()
+{
+ CloseHandle(m_imageReady);
+ EnterCriticalSection(&m_sect);
+ DeleteCriticalSection(&m_sect);
+ if (m_ImageData) delete m_ImageData;
+}
+
+STDMETHODIMP imTrackingGrabberCB::QueryInterface(REFIID riid, void ** ppv)
+{
+ if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) {
+ *ppv = (void *) static_cast<ISampleGrabberCB*> (this);
+ return NOERROR;
+ }
+ return E_NOINTERFACE;
+}
+
+void imTrackingGrabberCB::SetImageSize(int width, int height)
+{
+ EnterCriticalSection(&m_sect);
+
+ // This can be done because the capture system always returns
+ // images that are a multiple of 4.
+ int new_size = width * height * 3;
+
+ if (!m_ImageData)
+ {
+ m_ImageData = (BYTE*)calloc(new_size, 1);
+ m_Width = width;
+ m_Height = height;
+ }
+
+ if (m_Width*m_Height < new_size)
+ m_ImageData = (BYTE*)realloc(m_ImageData, new_size);
+
+ m_Width = width;
+ m_Height = height;
+
+ LeaveCriticalSection(&m_sect);
+}
+
+STDMETHODIMP imTrackingGrabberCB::SampleCB(double, IMediaSample *pSample)
+{
+ if (!m_ImageData) return S_OK;
+
+ EnterCriticalSection(&m_sect);
+
+ int size = pSample->GetSize();
+ if (size > m_Width*m_Height*3)
+ {
+ LeaveCriticalSection(&m_sect);
+ return S_OK;
+ }
+
+ BYTE *pData;
+ pSample->GetPointer(&pData);
+ CopyMemory(m_ImageData, pData, size);
+ m_newImageFlag = 1;
+
+ LeaveCriticalSection(&m_sect);
+
+ SetEvent(m_imageReady);
+
+ return S_OK;
+}
+
+int imTrackingGrabberCB::GetImage(unsigned char* data, int color_mode, int timeout)
+{
+ if (timeout != 0)
+ {
+ DWORD ret = WaitForSingleObject(m_imageReady, timeout);
+ if (ret != WAIT_OBJECT_0)
+ return 0;
+ }
+
+ if (!TryEnterCriticalSection(&m_sect))
+ return 0;
+
+ if (m_newImageFlag == 1)
+ {
+ int count = m_Width*m_Height;
+ unsigned char* src_data = m_ImageData;
+
+ if (imColorModeSpace(color_mode) == IM_RGB)
+ {
+ if (imColorModeIsPacked(color_mode))
+ {
+ unsigned char* dst_data = data;
+ for (int i = 0; i < count; i++)
+ {
+ *(dst_data+2) = *src_data++;
+ *(dst_data+1) = *src_data++;
+ *dst_data = *src_data++;
+ dst_data += 3;
+ }
+ }
+ else
+ {
+ unsigned char* red = data;
+ unsigned char* green = data + count;
+ unsigned char* blue = data + 2*count;
+ for (int i = 0; i < count; i++)
+ {
+ *blue++ = *src_data++;
+ *green++ = *src_data++;
+ *red++ = *src_data++;
+ }
+ }
+ }
+ else
+ {
+ unsigned char* map = data;
+ for (int i = 0; i < count; i++)
+ {
+ *map++ = *src_data;
+ src_data += 3;
+ }
+ }
+
+ m_newImageFlag = 0;
+
+ LeaveCriticalSection(&m_sect);
+ return 1;
+ }
+
+ LeaveCriticalSection(&m_sect);
+ return 0;
+}
+
+
+/**************************************************************************
+ Direct Show Only
+***************************************************************************/
+
+
+struct vcDevice
+{
+ IBaseFilter *filter;
+ char vendorinfo[128];
+ char desc[128];
+ char ex_desc[256];
+ char path[512];
+};
+static vcDevice vc_DeviceList[VC_MAXVIDDEVICES];
+static int vc_DeviceCount = 0;
+
+static void vc_AddDevice(IBaseFilter *filter, char* desc, char* ex_desc, char* path, char* vendorinfo)
+{
+ int i = vc_DeviceCount;
+ vcDevice* device = &vc_DeviceList[i];
+
+ memset(device, 0, sizeof(vcDevice));
+
+ device->filter = filter;
+
+ if (!desc) desc = "device";
+ sprintf(device->desc, "%d - %s", i, desc);
+
+ if (ex_desc) strcpy(device->ex_desc, ex_desc);
+ if (path) strcpy(device->path, path);
+ if (vendorinfo) strcpy(device->vendorinfo, vendorinfo);
+
+ vc_DeviceCount++;
+}
+
+
+#ifdef VC_PRINT_ERROR_MESSAGES
+//#include <dxerr9.h>
+
+static int vc_ShowError(HRESULT hr)
+{
+ if (FAILED(hr))
+ {
+ TCHAR szErr[MAX_ERROR_TEXT_LEN];
+ DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); // Must link with quartz.lib
+ if (res == 0) wsprintf(szErr, "Unknown Error: 0x%2x", hr);
+ MessageBox(0, szErr, "imCapture Error!", MB_OK | MB_ICONERROR);
+// MessageBox(NULL, DXGetErrorDescription9(hr), DXGetErrorString9(hr), MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ return 0;
+}
+
+#define VC_HARDFAILED(_x) vc_ShowError(_x)
+#else
+#define VC_HARDFAILED FAILED
+#endif
+
+static char* vc_Wide2Char(WCHAR* wstr)
+{
+ if (wstr)
+ {
+ int n = wcslen(wstr)+1;
+ char* str = (char*)malloc(n);
+ WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, n, NULL, NULL);
+ return str;
+ }
+
+ return NULL;
+}
+
+#ifdef VC_INCLUDE_VFW_DEVICES
+#define VC_CATEGORY_FLAG 0
+#else
+#define VC_CATEGORY_FLAG CDEF_DEVMON_FILTER|CDEF_DEVMON_PNP_DEVICE
+#endif
+
+static char* vc_GetDeviceProp(IPropertyBag *pPropBag, const WCHAR* PropName)
+{
+ VARIANT varProp;
+ VariantInit(&varProp);
+ HRESULT hr = pPropBag->Read(PropName, &varProp, 0);
+ if (SUCCEEDED(hr))
+ {
+ char* str = vc_Wide2Char(varProp.bstrVal);
+ VariantClear(&varProp);
+ return str;
+ }
+ return NULL;
+}
+
+static void vc_EnumerateDevices(void)
+{
+ // Selecting a Capture Device
+ ICreateDevEnum *pDevEnum = NULL;
+ IEnumMoniker *pEnum = NULL;
+
+ CoInitialize(NULL);
+
+ // Create the System Device Enumerator.
+ HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
+ CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
+ reinterpret_cast<void**>(&pDevEnum));
+ if (FAILED(hr)) return;
+
+ // Create an enumerator for the video capture category.
+ hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, VC_CATEGORY_FLAG);
+ if (FAILED(hr) || !pEnum)
+ {
+ pDevEnum->Release();
+ return;
+ }
+
+ IMoniker *pMoniker = NULL;
+ while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
+ {
+ IBaseFilter *capture_filter = NULL;
+ hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&capture_filter);
+ if (FAILED(hr))
+ {
+ pMoniker->Release();
+ continue; // Skip this one, maybe the next one will work.
+ }
+
+ IPropertyBag *pPropBag;
+ hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
+ if (FAILED(hr))
+ {
+ capture_filter->Release();
+ pMoniker->Release();
+ continue; // Skip this one, maybe the next one will work.
+ }
+
+ char* desc = vc_GetDeviceProp(pPropBag, L"FriendlyName");
+ char* ex_desc = vc_GetDeviceProp(pPropBag, L"Description");
+ char* path = vc_GetDeviceProp(pPropBag, L"DevicePath");
+
+ char* vendorinfo = NULL;
+ LPWSTR VendorInfo;
+ if (capture_filter->QueryVendorInfo(&VendorInfo) == S_OK)
+ {
+ vendorinfo = vc_Wide2Char(VendorInfo);
+ CoTaskMemFree(VendorInfo);
+ }
+
+ vc_AddDevice(capture_filter, desc, ex_desc, path, vendorinfo);
+
+ if (desc) free(desc);
+ if (ex_desc) free(ex_desc);
+ if (path) free(path);
+ if (vendorinfo) free(vendorinfo);
+
+ pPropBag->Release();
+ pMoniker->Release();
+ }
+
+ pEnum->Release();
+ pDevEnum->Release();
+}
+
+static IPin* vc_GetPin(IBaseFilter* pFilter, PIN_DIRECTION dir)
+{
+ IEnumPins* pEnumPins = NULL;
+ IPin* pPin = NULL;
+
+ pFilter->EnumPins(&pEnumPins);
+ if(!pEnumPins)
+ return NULL;
+
+ for(;;)
+ {
+ ULONG cFetched = 0;
+ PIN_DIRECTION pinDir = PIN_DIRECTION(-1);
+ pPin = 0;
+
+ if (FAILED(pEnumPins->Next(1, &pPin, &cFetched)))
+ {
+ pEnumPins->Release();
+ return NULL;
+ }
+
+ if(cFetched == 1 && pPin != 0)
+ {
+ pPin->QueryDirection(&pinDir);
+ if(pinDir == dir) break;
+ pPin->Release();
+ }
+ }
+
+ pEnumPins->Release();
+ return pPin;
+}
+
+static void vc_NukeDownstream(IGraphBuilder* filter_builder, IBaseFilter *filter)
+{
+ IPin *pPin=0, *pPinTo=0;
+ IEnumPins *pEnumPins = NULL;
+ PIN_INFO pininfo;
+
+ HRESULT hr = filter->EnumPins(&pEnumPins);
+ if (FAILED(hr)) return;
+
+ pEnumPins->Reset();
+
+ while(hr == NOERROR)
+ {
+ hr = pEnumPins->Next(1, &pPin, NULL);
+ if(hr == S_OK && pPin)
+ {
+ pPin->ConnectedTo(&pPinTo);
+ if(pPinTo)
+ {
+ hr = pPinTo->QueryPinInfo(&pininfo);
+ if(hr == NOERROR)
+ {
+ if(pininfo.dir == PINDIR_INPUT)
+ {
+ vc_NukeDownstream(filter_builder, pininfo.pFilter);
+ filter_builder->Disconnect(pPinTo);
+ filter_builder->Disconnect(pPin);
+ filter_builder->RemoveFilter(pininfo.pFilter);
+ }
+
+ pininfo.pFilter->Release();
+ }
+
+ pPinTo->Release();
+ }
+
+ pPin->Release();
+ }
+ }
+
+ pEnumPins->Release();
+}
+
+static int vc_DisconnectFilters(IGraphBuilder* filter_builder, IBaseFilter* source, IBaseFilter* destiny)
+{
+ IPin *pOut = vc_GetPin(source, PINDIR_OUTPUT);
+ IPin *pIn = vc_GetPin(destiny, PINDIR_INPUT);
+ HRESULT hr = filter_builder->Disconnect(pOut);
+ hr = filter_builder->Disconnect(pIn);
+ pOut->Release();
+ pIn->Release();
+ if (VC_HARDFAILED(hr)) return 0;
+ return 1;
+}
+
+static int vc_DisconnectFilterPin(IGraphBuilder* filter_builder, IBaseFilter* filter, PIN_DIRECTION dir)
+{
+ IPin *pIn = vc_GetPin(filter, dir);
+ IPin *pOut;
+ pIn->ConnectedTo(&pOut);
+
+ HRESULT hr = filter_builder->Disconnect(pIn);
+ pIn->Release();
+ if (VC_HARDFAILED(hr))
+ {
+ if (pOut) pOut->Release();
+ return 0;
+ }
+
+ if (pOut)
+ {
+ hr = filter_builder->Disconnect(pOut);
+ pOut->Release();
+
+ if (VC_HARDFAILED(hr))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int vc_ConnectFilters(IGraphBuilder* filter_builder, IBaseFilter* source, IBaseFilter* destiny, int direct)
+{
+ HRESULT hr;
+ IPin *pOut = vc_GetPin(source, PINDIR_OUTPUT);
+ IPin *pIn = vc_GetPin(destiny, PINDIR_INPUT);
+ if (direct)
+ hr = filter_builder->ConnectDirect(pOut, pIn, NULL);
+ else
+ hr = filter_builder->Connect(pOut, pIn);
+ pOut->Release();
+ pIn->Release();
+ if (VC_HARDFAILED(hr)) return 0;
+ return 1;
+}
+
+static DWORD vc_AddGraphToRot(IUnknown *pUnkGraph)
+{
+ IMoniker * pMoniker;
+ IRunningObjectTable *pROT;
+ WCHAR wsz[128];
+ HRESULT hr;
+
+ if (FAILED(GetRunningObjectTable(0, &pROT)))
+ return 0;
+
+ wsprintfW(wsz, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
+
+ hr = CreateItemMoniker(L"!", wsz, &pMoniker);
+ if (SUCCEEDED(hr))
+ {
+ DWORD dwRegister;
+ hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker, &dwRegister);
+ pROT->Release();
+
+ pMoniker->Release();
+
+ if (SUCCEEDED(hr))
+ return dwRegister;
+ }
+
+ pROT->Release();
+ return 0;
+}
+
+static void vc_RemoveGraphFromRot(DWORD pdwRegister)
+{
+ IRunningObjectTable *pROT;
+
+ if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
+ {
+ pROT->Revoke(pdwRegister);
+ pROT->Release();
+ }
+}
+
+/**************************************************************************
+ imVideoCapture
+***************************************************************************/
+
+typedef int (*vcDialogFunc)(imVideoCapture* vc, HWND parent);
+
+struct _imVideoCapture
+{
+ int registered_graph,
+ live,
+ device; /* current connected device. -1 if not connected. */
+
+ char* dialog_desc[6];
+ vcDialogFunc dialog_func[6];
+ int dialog_count; /* number of available configuration dialogs for the current connection. */
+
+ IGraphBuilder* filter_builder; /* The Filter Graph Manager */
+ ICaptureGraphBuilder2* capture_graph_builder; /* Helps the Filter Graph Manager */
+ IBaseFilter* capture_filter; /* the capture device (can vary), it's a source filter. */
+ IBaseFilter* grabber_filter; /* returns the capture data, it's a transform filter */
+ IBaseFilter* null_filter; /* does nothing, act as a terminator, it's a rendering filter */
+ ISampleGrabber* sample_grabber; /* Used to access the ISampleGrabber interface, since grabber_filter is a generic IBaseFilter interface based on ISampleGrabber. */
+ IMediaControl* media_control; /* Used to Run and Stop the graph flow. */
+ IBaseFilter* overlay_renderer; /* Used when there is a video port without a preview */
+ IBaseFilter *overlay_mixer;
+
+ IAMVideoProcAmp* video_prop; /* Used to set/get video properties */
+ IAMCameraControl* camera_prop; /* Used to set/get camera properties */
+ IAMVideoControl* videoctrl_prop; /* Used to set/get video properties */
+
+ imTrackingGrabberCB* sample_callback; /* Used to intercept the samples. */
+
+ int format_count; /* number of supported formats */
+ int format_current; /* current format */
+ int format_map[50]; /* table to map returned formats to direct X formats */
+};
+
+int imVideoCaptureDeviceCount(void)
+{
+ return vc_DeviceCount;
+}
+
+int imVideoCaptureReloadDevices(void)
+{
+ for (int i = 0; i < vc_DeviceCount; i++)
+ {
+ vc_DeviceList[i].filter->Release();
+ }
+
+ vc_DeviceCount = 0;
+ vc_EnumerateDevices();
+ return vc_DeviceCount;
+}
+
+static int vc_CheckDeviceList(int device)
+{
+ // List available Devices once
+ if (vc_DeviceCount == 0)
+ {
+ vc_EnumerateDevices();
+
+ if (vc_DeviceCount == 0)
+ return 0;
+ }
+
+ if (device < 0 || device >= vc_DeviceCount)
+ return 0;
+
+ return 1;
+}
+
+const char* imVideoCaptureDeviceDesc(int device)
+{
+ if (!vc_CheckDeviceList(device))
+ return NULL;
+
+ return vc_DeviceList[device].desc;
+}
+
+const char* imVideoCaptureDeviceExDesc(int device)
+{
+ if (!vc_CheckDeviceList(device))
+ return NULL;
+
+ return vc_DeviceList[device].ex_desc;
+}
+
+const char* imVideoCaptureDevicePath(int device)
+{
+ if (!vc_CheckDeviceList(device))
+ return NULL;
+
+ return vc_DeviceList[device].path;
+}
+
+const char* imVideoCaptureDeviceVendorInfo(int device)
+{
+ if (!vc_CheckDeviceList(device))
+ return NULL;
+
+ return vc_DeviceList[device].vendorinfo;
+}
+
+#define vc_SafeRelease(_p) { if( (_p) != 0 ) { (_p)->Release(); (_p)= NULL; } }
+
+static void vc_CheckVideoPort(imVideoCapture* vc)
+{
+/*
+ If the video capture card supports the video port pin without a video preview pin this will not work.
+ The DirectShow architecture requires that the video port pin be connected to the Overlay Mixer Filter.
+ If this pin is not connected, data cannot be captured in DirectShow.
+*/
+ HRESULT hr;
+
+ IPin *pPreviewPin = NULL;
+ hr = vc->capture_graph_builder->FindPin(
+ vc->capture_filter, // Pointer to the capture filter.
+ PINDIR_OUTPUT, // Look for an output pin.
+ &PIN_CATEGORY_PREVIEW, // Look for a preview pin.
+ NULL, // Any media type.
+ FALSE, // Pin can be connected.
+ 0, // Retrieve the first matching pin.
+ &pPreviewPin // Receives a pointer to the pin.
+ );
+ if (hr == S_OK)
+ {
+ pPreviewPin->Release();
+ return;
+ }
+
+ IPin *pVideoPortPin = NULL;
+ hr = vc->capture_graph_builder->FindPin(
+ vc->capture_filter, // Pointer to the capture filter.
+ PINDIR_OUTPUT, // Look for an output pin.
+ &PIN_CATEGORY_VIDEOPORT, // Look for a video port pin.
+ NULL, // Any media type.
+ FALSE, // Pin can be connected.
+ 0, // Retrieve the first matching pin.
+ &pVideoPortPin // Receives a pointer to the pin.
+ );
+ if (FAILED(hr)) return;
+
+ // Create the overlay mixer.
+ CoCreateInstance(CLSID_OverlayMixer, NULL, CLSCTX_INPROC,
+ IID_IBaseFilter, (void **)&vc->overlay_mixer);
+
+ // Add it to the filter graph.
+ vc->filter_builder->AddFilter(vc->overlay_mixer, L"Overlay Mixer");
+
+ IPin *pOverlayPin = NULL;
+ vc->capture_graph_builder->FindPin(vc->overlay_mixer, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pOverlayPin);
+
+ vc->filter_builder->Connect(pVideoPortPin, pOverlayPin);
+ if (FAILED(hr)) return;
+
+ vc_SafeRelease(pVideoPortPin);
+ vc_SafeRelease(pOverlayPin);
+
+ CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
+ IID_IBaseFilter, reinterpret_cast<void**>(&vc->overlay_renderer));
+ vc->filter_builder->AddFilter(vc->overlay_renderer, L"Overlay Renderer");
+
+ vc_ConnectFilters(vc->filter_builder, vc->overlay_mixer, vc->overlay_renderer, 1);
+
+ IVideoWindow* pVideoWindow = NULL;
+ vc->overlay_renderer->QueryInterface(IID_IVideoWindow,(void**)&pVideoWindow);
+ pVideoWindow->put_AutoShow(OAFALSE);
+ pVideoWindow->Release();
+}
+
+static void vc_ReleaseMixer(imVideoCapture* vc)
+{
+ IPin *pOverlayPin = vc_GetPin(vc->overlay_mixer, PINDIR_INPUT);
+ IPin *pVideoPortPin = NULL;
+ pOverlayPin->ConnectedTo(&pVideoPortPin);
+ vc->filter_builder->Disconnect(pOverlayPin);
+ vc->filter_builder->Disconnect(pVideoPortPin);
+ vc_SafeRelease(pVideoPortPin);
+ vc_SafeRelease(pOverlayPin);
+
+ vc_DisconnectFilters(vc->filter_builder, vc->overlay_mixer, vc->overlay_renderer);
+
+ vc->filter_builder->RemoveFilter(vc->overlay_renderer);
+ vc->filter_builder->RemoveFilter(vc->overlay_mixer);
+ vc_SafeRelease(vc->overlay_renderer);
+ vc_SafeRelease(vc->overlay_mixer);
+}
+
+static int vc_InitCaptureGraphBuilder(imVideoCapture* vc)
+{
+ HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
+ IID_ICaptureGraphBuilder2, reinterpret_cast<void**>(&vc->capture_graph_builder));
+ if (FAILED(hr)) return 0;
+
+ hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
+ IID_IGraphBuilder, reinterpret_cast<void**>(&vc->filter_builder));
+ if (FAILED(hr)) return 0;
+
+ hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
+ IID_IBaseFilter, reinterpret_cast<void**>(&vc->grabber_filter));
+ if (FAILED(hr)) return 0;
+
+ hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
+ IID_IBaseFilter, reinterpret_cast<void**>(&vc->null_filter));
+ if (FAILED(hr)) return 0;
+
+ // Initialize the Capture Graph Builder.
+ vc->capture_graph_builder->SetFiltergraph(vc->filter_builder);
+
+ hr = vc->filter_builder->QueryInterface(IID_IMediaControl,(void**)&vc->media_control);
+ hr = vc->grabber_filter->QueryInterface(IID_ISampleGrabber, (void **)&vc->sample_grabber);
+
+ AM_MEDIA_TYPE mt;
+ ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
+ mt.majortype = MEDIATYPE_Video;
+ mt.subtype = MEDIASUBTYPE_RGB24; // Force 24 bpp
+ vc->sample_grabber->SetMediaType(&mt);
+ vc->sample_grabber->SetOneShot(FALSE);
+ vc->sample_grabber->SetBufferSamples(FALSE);
+
+ vc->sample_callback = new imTrackingGrabberCB();
+
+ hr = vc->filter_builder->AddFilter(vc->grabber_filter, L"imSampleGrabber");
+ hr = vc->filter_builder->AddFilter(vc->null_filter, L"imNullRenderer");
+
+ // Remove clock to speed up things
+ IMediaFilter* pMediaFilter = NULL;
+ vc->filter_builder->QueryInterface(IID_IMediaFilter, (void**)&pMediaFilter);
+ pMediaFilter->SetSyncSource(NULL);
+ pMediaFilter->Release();
+
+#ifdef VC_REGISTER_FILTERGRAPH
+ vc->registered_graph = vc_AddGraphToRot(vc->filter_builder);
+#endif
+
+ return 1;
+}
+
+imVideoCapture* imVideoCaptureCreate(void)
+{
+ imVideoCapture* vc = (imVideoCapture*)malloc(sizeof(imVideoCapture));
+ memset(vc, 0, sizeof(imVideoCapture));
+
+ // List available Devices once
+ if (vc_DeviceCount == 0)
+ {
+ vc_EnumerateDevices();
+
+ if (vc_DeviceCount == 0)
+ {
+ free(vc);
+ return NULL;
+ }
+ }
+
+ if (!vc_InitCaptureGraphBuilder(vc))
+ {
+ vc_SafeRelease(vc->grabber_filter);
+ vc_SafeRelease(vc->filter_builder);
+ vc_SafeRelease(vc->capture_graph_builder);
+ vc_SafeRelease(vc->null_filter);
+ free(vc);
+ return NULL;
+ }
+
+ vc->device = -1;
+
+ return vc;
+}
+
+static void vc_CaptureRemove(imVideoCapture* vc)
+{
+ vc->filter_builder->RemoveFilter(vc->capture_filter);
+
+ vc->capture_filter = NULL; /* do not release here */
+ vc_SafeRelease(vc->video_prop);
+ vc_SafeRelease(vc->camera_prop);
+ vc_SafeRelease(vc->videoctrl_prop);
+
+ vc->dialog_count = 0;
+ vc->live = 0;
+ vc->device = -1;
+}
+
+void imVideoCaptureDestroy(imVideoCapture* vc)
+{
+ assert(vc);
+
+#ifdef VC_REGISTER_FILTERGRAPH
+ if (vc->registered_graph) vc_RemoveGraphFromRot(vc->registered_graph);
+#endif
+
+ imVideoCaptureDisconnect(vc);
+
+ delete vc->sample_callback;
+
+ vc_SafeRelease(vc->overlay_mixer);
+ vc_SafeRelease(vc->overlay_renderer);
+ vc_SafeRelease(vc->media_control);
+ vc_SafeRelease(vc->sample_grabber);
+
+ vc->null_filter->Release();
+ vc->grabber_filter->Release();
+ vc->filter_builder->Release();
+ vc->capture_graph_builder->Release();
+
+ free(vc);
+}
+
+static void vc_StopLive(imVideoCapture* vc)
+{
+ if (vc->live) // If it is live, stop it
+ {
+ vc->media_control->Stop();
+ Sleep(VC_CAMERADELAY);
+ }
+}
+
+static int vc_StartLive(imVideoCapture* vc)
+{
+ if (vc->live) // If it should be started, start it
+ {
+ HRESULT hr = vc->media_control->Run();
+ if (VC_HARDFAILED(hr))
+ {
+ vc->live = 0;
+ return 0;
+ }
+
+ Sleep(VC_CAMERADELAY);
+ }
+
+ return 1;
+}
+
+int imVideoCaptureOneFrame(imVideoCapture* vc, unsigned char* data, int color_mode)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ vc_StopLive(vc);
+ vc->live = 0;
+
+ vc->sample_grabber->SetOneShot(TRUE);
+
+ vc->live = 1;
+ if (!vc_StartLive(vc))
+ {
+ vc->sample_grabber->SetOneShot(FALSE);
+ return 0;
+ }
+
+ int ret = imVideoCaptureFrame(vc, data, color_mode, -1);
+
+ vc_StopLive(vc);
+ vc->live = 0;
+
+ vc->sample_grabber->SetOneShot(FALSE);
+
+ return ret;
+}
+
+int imVideoCaptureFrame(imVideoCapture* vc, unsigned char* data, int color_mode, int timeout)
+{
+ assert(vc);
+ assert(vc->device != -1);
+ assert(vc->live);
+ return vc->sample_callback->GetImage(data, color_mode, timeout);
+}
+
+static int vc_CaptureDisconnect(imVideoCapture* vc)
+{
+ vc->sample_grabber->SetCallback(NULL, 0);
+
+ if (vc->overlay_mixer)
+ vc_ReleaseMixer(vc);
+
+ vc_DisconnectFilters(vc->filter_builder, vc->grabber_filter, vc->null_filter);
+
+ // Disconnect the grabber to preserve it
+ if (!vc_DisconnectFilterPin(vc->filter_builder, vc->grabber_filter, PINDIR_INPUT))
+ return 0;
+
+ // Remove everything downstream the capture filter, except the null renderer
+ vc_NukeDownstream(vc->filter_builder, vc->capture_filter);
+
+ return 1;
+}
+
+void imVideoCaptureDisconnect(imVideoCapture* vc)
+{
+ assert(vc);
+
+ if (vc->device == -1)
+ return;
+
+ vc_StopLive(vc);
+ vc->live = 0;
+
+ vc_CaptureDisconnect(vc);
+ vc_CaptureRemove(vc);
+}
+
+static void vc_UpdateSize(imVideoCapture* vc)
+{
+ int width, height;
+ imVideoCaptureGetImageSize(vc, &width, &height);
+ vc->sample_callback->SetImageSize(width, height);
+}
+
+static void vc_UpdateDialogs(imVideoCapture* vc);
+static void vc_UpdateFormatList(imVideoCapture* vc);
+
+static int vc_CaptureConnect(imVideoCapture* vc)
+{
+ vc_CheckVideoPort(vc);
+
+ if (!vc_ConnectFilters(vc->filter_builder, vc->capture_filter, vc->grabber_filter, 0))
+ {
+ vc_CaptureRemove(vc);
+ return 0;
+ }
+
+ vc_ConnectFilters(vc->filter_builder, vc->grabber_filter, vc->null_filter, 1);
+
+ vc_UpdateDialogs(vc);
+ vc_UpdateFormatList(vc);
+ vc_UpdateSize(vc);
+ vc->sample_grabber->SetCallback(vc->sample_callback, 0); // associate the sample_grabber with the sample_callback
+
+ return 1;
+}
+
+int imVideoCaptureConnect(imVideoCapture* vc, int device)
+{
+ assert(vc);
+
+ if (device == -1)
+ return vc->device;
+
+ if (device == vc->device)
+ return 1;
+
+ if (device < -1 || device > vc_DeviceCount)
+ return 0;
+
+ if (vc->device != -1)
+ imVideoCaptureDisconnect(vc);
+
+ vc->capture_filter = vc_DeviceList[device].filter;
+ if (!vc->capture_filter)
+ return 0;
+
+ vc->filter_builder->AddFilter(vc->capture_filter, L"imCaptureSource");
+ vc->device = device;
+
+ if (!vc_CaptureConnect(vc))
+ return 0;
+
+ return 1;
+}
+
+int imVideoCaptureLive(imVideoCapture* vc, int live)
+{
+ assert(vc);
+
+ if (live == -1)
+ return vc->live;
+
+ if (vc->device == -1)
+ return 0;
+
+ if (live == vc->live)
+ return 1;
+
+ if (live)
+ {
+ vc->live = 1;
+ if (!vc_StartLive(vc))
+ return 0;
+ }
+ else
+ {
+ vc_StopLive(vc);
+ vc->live = 0;
+ }
+
+ return 1;
+}
+
+
+/**************************************************************************
+ Format and Size
+***************************************************************************/
+
+
+void imVideoCaptureGetImageSize(imVideoCapture* vc, int *width, int *height)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ AM_MEDIA_TYPE mt;
+ ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
+ HRESULT hr = vc->sample_grabber->GetConnectedMediaType(&mt);
+
+ if ( SUCCEEDED(hr) &&
+ (mt.majortype == MEDIATYPE_Video) &&
+ (mt.formattype == FORMAT_VideoInfo) &&
+ (mt.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
+ (mt.pbFormat != NULL))
+ {
+ VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)mt.pbFormat;
+ *width = pVih->bmiHeader.biWidth;
+ *height = abs(pVih->bmiHeader.biHeight);
+ CoTaskMemFree((PVOID)mt.pbFormat);
+ }
+ else
+ {
+ *width = 0;
+ *height = 0;
+ }
+}
+
+static IIPDVDec* vc_GetDVDecoder(imVideoCapture* vc)
+{
+ IIPDVDec *pDV = NULL;
+ HRESULT hr = vc->capture_graph_builder->FindInterface(NULL,
+ &MEDIATYPE_Video, vc->capture_filter, IID_IIPDVDec, (void **)&pDV);
+ if(FAILED(hr))
+ return NULL;
+
+ return pDV;
+}
+
+static IAMStreamConfig* vc_GetStreamConfig(imVideoCapture* vc)
+{
+ IAMStreamConfig *pSC = NULL;
+ if (FAILED(vc->capture_graph_builder->FindInterface(&PIN_CATEGORY_CAPTURE,
+ &MEDIATYPE_Video, vc->capture_filter, IID_IAMStreamConfig, (void **)&pSC)))
+ return NULL;
+
+ return pSC;
+}
+
+static void vc_DeleteMediaType(AM_MEDIA_TYPE *pmt)
+{
+ CoTaskMemFree((PVOID)pmt->pbFormat);
+ CoTaskMemFree(pmt);
+}
+
+static int vc_SetStreamSize(imVideoCapture* vc, int width, int height)
+{
+ IAMStreamConfig *pSC = vc_GetStreamConfig(vc);
+ if (!pSC) return 0;
+
+ AM_MEDIA_TYPE *pmt;
+ HRESULT hr = pSC->GetFormat(&pmt);
+ if (FAILED(hr)) return 0;
+
+ VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->pbFormat;
+ BITMAPINFOHEADER* bih = &vih->bmiHeader;
+
+ /* dibs are DWORD aligned */
+ int data_size = height * ((width * bih->biBitCount + 31) / 32) * 4; /* 4 bytes boundary */
+
+ bih->biSize = sizeof(BITMAPINFOHEADER);
+ bih->biHeight = height;
+ bih->biWidth = width;
+ bih->biSizeImage = data_size;
+
+ int fps = 30; // desired frame rate
+ vih->dwBitRate = fps * data_size;
+ vih->AvgTimePerFrame = 10000000 / fps;
+
+ pmt->cbFormat = sizeof(VIDEOINFOHEADER);
+ pmt->lSampleSize = data_size;
+
+ hr = pSC->SetFormat(pmt);
+ pSC->Release();
+
+ vc_DeleteMediaType(pmt);
+
+ return SUCCEEDED(hr);
+}
+
+static int vc_SetImageSize(imVideoCapture* vc, int width, int height)
+{
+ IIPDVDec* pDV = vc_GetDVDecoder(vc);
+ if (pDV)
+ {
+ int size = 0;
+
+ switch(width)
+ {
+ case 720:
+ size = DVRESOLUTION_FULL;
+ break;
+ case 360:
+ size = DVRESOLUTION_HALF;
+ break;
+ case 180:
+ size = DVRESOLUTION_QUARTER;
+ break;
+ case 88:
+ size = DVRESOLUTION_DC;
+ break;
+ }
+
+ if (!size)
+ return 0;
+
+ int ret = SUCCEEDED(pDV->put_IPDisplay(size));
+ if (ret)
+ vc->sample_callback->SetImageSize(width, height);
+
+ return ret;
+ }
+
+ int ret = vc_SetStreamSize(vc, width, height);
+ if (ret)
+ vc->sample_callback->SetImageSize(width, height);
+
+ return ret;
+}
+
+int imVideoCaptureSetImageSize(imVideoCapture* vc, int width, int height)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ vc_StopLive(vc);
+
+ // must be disconnected to change size or format
+ vc_CaptureDisconnect(vc);
+
+ int ret = vc_SetImageSize(vc, width, height);
+
+ if (!vc_CaptureConnect(vc))
+ ret = 0;
+
+ vc_StartLive(vc);
+
+ return ret;
+}
+
+static void vc_UpdateFormatList(imVideoCapture* vc)
+{
+ vc->format_count = 0;
+ vc->format_current = -1;
+
+ IAMStreamConfig *pSC = vc_GetStreamConfig(vc);
+ if (!pSC) return;
+
+ int iCount = 0, iSize = 0;
+ if (FAILED(pSC->GetNumberOfCapabilities(&iCount, &iSize)))
+ {
+ pSC->Release();
+ return;
+ }
+
+ AM_MEDIA_TYPE *curr_pmt;
+ HRESULT hr = pSC->GetFormat(&curr_pmt);
+ if (FAILED(hr))
+ {
+ pSC->Release();
+ return;
+ }
+
+ for (int iFormat = 0; iFormat < iCount; iFormat++)
+ {
+ VIDEO_STREAM_CONFIG_CAPS scc;
+ AM_MEDIA_TYPE *pmt;
+ if (SUCCEEDED(pSC->GetStreamCaps(iFormat, &pmt, (BYTE*)&scc)))
+ {
+ if (scc.guid == FORMAT_VideoInfo)
+ {
+ VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)curr_pmt->pbFormat;
+ BITMAPINFOHEADER* bih = &vih->bmiHeader;
+ int width = bih->biWidth;
+ int height = abs(bih->biHeight);
+
+ if (curr_pmt->subtype == pmt->subtype &&
+ width == scc.InputSize.cx &&
+ height == scc.InputSize.cy)
+ {
+ vc->format_current = vc->format_count;
+ }
+
+ vc->format_map[vc->format_count] = iFormat;
+ vc->format_count++;
+ }
+
+ vc_DeleteMediaType(pmt);
+ }
+ }
+
+ vc_DeleteMediaType(curr_pmt);
+ pSC->Release();
+}
+
+int imVideoCaptureFormatCount(imVideoCapture* vc)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ return vc->format_count;
+}
+
+static void vc_GetFormatName(GUID subtype, char* desc)
+{
+#define VC_NUM_FORMATS 7
+ typedef struct _guid2name {
+ char* name;
+ const GUID* subtype;
+ } guid2name;
+ static guid2name map_table[VC_NUM_FORMATS] = {
+ {"RGB1",&MEDIASUBTYPE_RGB1},
+ {"RGB4",&MEDIASUBTYPE_RGB4},
+ {"RGB8",&MEDIASUBTYPE_RGB8},
+ {"RGB565",&MEDIASUBTYPE_RGB565},
+ {"RGB555",&MEDIASUBTYPE_RGB555},
+ {"RGB24",&MEDIASUBTYPE_RGB24},
+ {"RGB32",&MEDIASUBTYPE_RGB32}
+ };
+
+ for (int i = 0; i < VC_NUM_FORMATS; i++)
+ {
+ if (*(map_table[i].subtype) == subtype)
+ {
+ strcpy(desc, map_table[i].name);
+ return;
+ }
+ }
+
+ desc[0] = (char)(subtype.Data1);
+ desc[1] = (char)(subtype.Data1 >> 8);
+ desc[2] = (char)(subtype.Data1 >> 16);
+ desc[3] = (char)(subtype.Data1 >> 32);
+ desc[4] = 0;
+}
+
+int imVideoCaptureGetFormat(imVideoCapture* vc, int format, int *width, int *height, char* desc)
+{
+ assert(vc);
+ assert(vc->device != -1);
+ assert(vc->format_count);
+
+ if (format >= vc->format_count)
+ return 0;
+
+ IAMStreamConfig *pSC = vc_GetStreamConfig(vc);
+ if (!pSC) return 0;
+
+ VIDEO_STREAM_CONFIG_CAPS scc;
+ AM_MEDIA_TYPE *pmt;
+ if (SUCCEEDED(pSC->GetStreamCaps(vc->format_map[format], &pmt, (BYTE*)&scc)))
+ {
+ *width = scc.InputSize.cx;
+ *height = scc.InputSize.cy;
+ vc_GetFormatName(pmt->subtype, desc);
+
+ pSC->Release();
+ vc_DeleteMediaType(pmt);
+ return 1;
+ }
+
+ pSC->Release();
+ return 0;
+}
+
+static int vc_SetStreamFormat(imVideoCapture* vc, int format)
+{
+ IAMStreamConfig *pSC = vc_GetStreamConfig(vc);
+ if (!pSC) return 0;
+
+ VIDEO_STREAM_CONFIG_CAPS scc;
+ AM_MEDIA_TYPE *pmt;
+ if (FAILED(pSC->GetStreamCaps(vc->format_map[format], &pmt, (BYTE*)&scc)))
+ {
+ pSC->Release();
+ return 0;
+ }
+
+ pSC->SetFormat(pmt);
+ pSC->Release();
+
+ vc->sample_callback->SetImageSize(scc.InputSize.cx, scc.InputSize.cy);
+
+ vc_DeleteMediaType(pmt);
+
+ return 1;
+}
+
+int imVideoCaptureSetFormat(imVideoCapture* vc, int format)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ if (format == -1)
+ return vc->format_current;
+
+ if (format >= vc->format_count)
+ return 0;
+
+ vc_StopLive(vc);
+
+ // must be disconnected to change size or format
+ vc_CaptureDisconnect(vc);
+
+ int ok = vc_SetStreamFormat(vc, format);
+
+ if (!vc_CaptureConnect(vc))
+ ok = 0;
+
+ if (ok)
+ vc->format_current = format;
+
+ vc_StartLive(vc);
+
+ return ok;
+}
+
+
+/**************************************************************************
+ Dialogs
+***************************************************************************/
+
+
+static ISpecifyPropertyPages* vc_GetPropertyPages(IUnknown* obj)
+{
+ ISpecifyPropertyPages *pSpec = NULL;
+
+ HRESULT hr = obj->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpec);
+ if (FAILED(hr)) return NULL;
+
+ CAUUID cauuid;
+ hr = pSpec->GetPages(&cauuid);
+ CoTaskMemFree(cauuid.pElems);
+
+ if (FAILED(hr))
+ {
+ pSpec->Release();
+ return NULL;
+ }
+
+ return pSpec;
+}
+
+static int vc_ShowPropertyPages(HWND parent, IUnknown* obj, WCHAR* title)
+{
+ ISpecifyPropertyPages *pSpec = vc_GetPropertyPages(obj);
+
+ CAUUID cauuid;
+ pSpec->GetPages(&cauuid);
+
+ HRESULT hr = OleCreatePropertyFrame(parent, 30, 30, title, 1,
+ &obj, cauuid.cElems, (GUID *)cauuid.pElems, 0, 0, NULL);
+
+ CoTaskMemFree(cauuid.pElems);
+ pSpec->Release();
+
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static IAMVfwCaptureDialogs* vc_getVfwDialogs(imVideoCapture* vc)
+{
+ IAMVfwCaptureDialogs* pDlg = NULL;
+ HRESULT hr = vc->capture_graph_builder->FindInterface(&PIN_CATEGORY_CAPTURE,
+ &MEDIATYPE_Video, vc->capture_filter, IID_IAMVfwCaptureDialogs, (void **)&pDlg);
+
+ if (FAILED(hr))
+ return NULL;
+
+ return pDlg;
+}
+
+static int vc_ShowVfwDialog(imVideoCapture* vc, HWND parent, VfwCaptureDialogs dialog)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ IAMVfwCaptureDialogs *pDlg = vc_getVfwDialogs(vc);
+ if(!pDlg) return 0;
+
+ HRESULT hr = pDlg->HasDialog(dialog);
+ if (FAILED(hr))
+ {
+ pDlg->Release();
+ return 0;
+ }
+
+ int ret = 0;
+ vc_StopLive(vc);
+
+ // must be disconnected to change size or format
+ vc_CaptureDisconnect(vc);
+
+ hr = pDlg->ShowDialog(dialog, parent);
+ if (SUCCEEDED(hr))
+ ret = 1;
+
+ if (!vc_CaptureConnect(vc))
+ ret = 0;
+
+ vc_StartLive(vc);
+
+ pDlg->Release();
+ return ret;
+}
+
+static int vc_ShowVfwFormatDialog(imVideoCapture* vc, HWND parent)
+{
+ return vc_ShowVfwDialog(vc, parent, VfwCaptureDialog_Format);
+}
+
+static int vc_ShowVfwSourceDialog(imVideoCapture* vc, HWND parent)
+{
+ return vc_ShowVfwDialog(vc, parent, VfwCaptureDialog_Source);
+}
+
+static int vc_ShowVfwDisplayDialog(imVideoCapture* vc, HWND parent)
+{
+ return vc_ShowVfwDialog(vc, parent, VfwCaptureDialog_Display);
+}
+
+static int vc_ShowFormatDialog(imVideoCapture* vc, HWND parent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ IAMStreamConfig *pSC = vc_GetStreamConfig(vc);
+ if (!pSC) return 0;
+
+ vc_StopLive(vc);
+
+ // must be disconnected to change size or format
+ vc_CaptureDisconnect(vc);
+
+ int ok = vc_ShowPropertyPages(parent, (IUnknown*)pSC, L"Format");
+ pSC->Release();
+
+ if (!vc_CaptureConnect(vc))
+ ok = 0;
+
+ vc_StartLive(vc);
+
+ return ok;
+}
+
+static int vc_ShowSourceDialog(imVideoCapture* vc, HWND parent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ return vc_ShowPropertyPages(parent, (IUnknown*)vc->capture_filter, L"Source");
+}
+
+static IAMTVTuner* vc_GetTVTuner(imVideoCapture* vc)
+{
+ IAMTVTuner *pTVT = NULL;
+
+ HRESULT hr = vc->capture_graph_builder->FindInterface(&PIN_CATEGORY_CAPTURE,
+ &MEDIATYPE_Video, vc->capture_filter, IID_IAMTVTuner, (void **)&pTVT);
+ if(FAILED(hr))
+ return NULL;
+
+ return pTVT;
+}
+
+static int vc_ShowTVTunerDialog(imVideoCapture* vc, HWND parent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ IAMTVTuner* pTVT = vc_GetTVTuner(vc);
+ if (!pTVT)
+ return 0;
+
+ int ret = vc_ShowPropertyPages(parent, (IUnknown*)pTVT, L"TV Turner");
+ pTVT->Release();
+ return ret;
+}
+
+static IAMCrossbar* vc_GetCrossBar(imVideoCapture* vc)
+{
+ IAMCrossbar *pX = NULL;
+ HRESULT hr = vc->capture_graph_builder->FindInterface(&PIN_CATEGORY_CAPTURE,
+ &MEDIATYPE_Video, vc->capture_filter, IID_IAMCrossbar, (void **)&pX);
+ if(FAILED(hr))
+ return NULL;
+
+ return pX;
+}
+
+static int vc_ShowCrossbarDialog(imVideoCapture* vc, HWND parent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ IAMCrossbar* pX = vc_GetCrossBar(vc);
+ if (!pX)
+ return 0;
+
+ int ret = vc_ShowPropertyPages(parent, (IUnknown*)pX, L"Crossbar");
+ pX->Release();
+ return ret;
+}
+
+static IAMCrossbar* vc_GetSecondCrossBar(imVideoCapture* vc, IAMCrossbar *pX)
+{
+ IAMCrossbar *pX2 = NULL;
+ IBaseFilter *pXF;
+ HRESULT hr = pX->QueryInterface(IID_IBaseFilter, (void **)&pXF);
+ if(hr != S_OK) return NULL;
+
+ hr = vc->capture_graph_builder->FindInterface(&LOOK_UPSTREAM_ONLY,
+ NULL, pXF, IID_IAMCrossbar, (void **)&pX2);
+ pXF->Release();
+ if(FAILED(hr)) return NULL;
+
+ return pX2;
+}
+
+static int vc_ShowSecondCrossbarDialog(imVideoCapture* vc, HWND parent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ IAMCrossbar* pX = vc_GetCrossBar(vc);
+ if (!pX)
+ return 0;
+
+ IAMCrossbar* pX2 = vc_GetSecondCrossBar(vc, pX);
+ if (!pX2)
+ {
+ pX->Release();
+ return 0;
+ }
+
+ int ret = vc_ShowPropertyPages(parent, (IUnknown*)pX2, L"Second Crossbar");
+ pX->Release();
+ pX2->Release();
+ return ret;
+}
+
+static int vc_ShowDVDecDialog(imVideoCapture* vc, HWND parent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ IIPDVDec* pDV = vc_GetDVDecoder(vc);
+ if (!pDV)
+ return 0;
+
+ vc_StopLive(vc);
+
+ int ret = vc_ShowPropertyPages(parent, (IUnknown*)pDV, L"DV Decoder");
+ pDV->Release();
+
+ vc_StartLive(vc);
+
+ return ret;
+}
+
+static void vc_UpdateDialogs(imVideoCapture* vc)
+{
+ vc->dialog_count = 0;
+
+ IAMVfwCaptureDialogs *pDlg = vc_getVfwDialogs(vc);
+ if(pDlg)
+ {
+ if(pDlg->HasDialog(VfwCaptureDialog_Format) == S_OK)
+ {
+ vc->dialog_desc[vc->dialog_count] = "Format... (VFW)";
+ vc->dialog_func[vc->dialog_count] = vc_ShowVfwFormatDialog;
+ vc->dialog_count++;
+ }
+
+ if(pDlg->HasDialog(VfwCaptureDialog_Source) == S_OK)
+ {
+ vc->dialog_desc[vc->dialog_count] = "Source... (VFW)";
+ vc->dialog_func[vc->dialog_count] = vc_ShowVfwSourceDialog;
+ vc->dialog_count++;
+ }
+
+ if(pDlg->HasDialog(VfwCaptureDialog_Display) == S_OK)
+ {
+ vc->dialog_desc[vc->dialog_count] = "Display... (VFW)";
+ vc->dialog_func[vc->dialog_count] = vc_ShowVfwDisplayDialog;
+ vc->dialog_count++;
+ }
+
+ return;
+ }
+
+ ISpecifyPropertyPages *pSpec;
+ IAMStreamConfig *pSC = vc_GetStreamConfig(vc);
+ if (pSC)
+ {
+ pSpec = vc_GetPropertyPages((IUnknown*)pSC);
+ if (pSpec)
+ {
+ vc->dialog_desc[vc->dialog_count] = "Format...";
+ vc->dialog_func[vc->dialog_count] = vc_ShowFormatDialog;
+ vc->dialog_count++;
+ pSpec->Release();
+ }
+
+ pSC->Release();
+ }
+
+ pSpec = vc_GetPropertyPages((IUnknown*)vc->capture_filter);
+ if (pSpec)
+ {
+ vc->dialog_desc[vc->dialog_count] = "Source...";
+ vc->dialog_func[vc->dialog_count] = vc_ShowSourceDialog;
+ vc->dialog_count++;
+ pSpec->Release();
+ }
+
+ IIPDVDec* pDV = vc_GetDVDecoder(vc);
+ if (pDV)
+ {
+ pSpec = vc_GetPropertyPages((IUnknown*)pDV);
+ if (pSpec)
+ {
+ vc->dialog_desc[vc->dialog_count] = "DV Decoder...";
+ vc->dialog_func[vc->dialog_count] = vc_ShowDVDecDialog;
+ vc->dialog_count++;
+ pSpec->Release();
+ }
+
+ pDV->Release();
+ }
+
+ IAMCrossbar* pX = vc_GetCrossBar(vc);
+ if (pX)
+ {
+ pSpec = vc_GetPropertyPages((IUnknown*)pX);
+ if (pSpec)
+ {
+ vc->dialog_desc[vc->dialog_count] = "Crossbar...";
+ vc->dialog_func[vc->dialog_count] = vc_ShowCrossbarDialog;
+ vc->dialog_count++;
+ pSpec->Release();
+ }
+
+ IAMCrossbar* pX2 = vc_GetSecondCrossBar(vc, pX);
+ if (pX2)
+ {
+ pSpec = vc_GetPropertyPages((IUnknown*)pX2);
+ if (pSpec)
+ {
+ vc->dialog_desc[vc->dialog_count] = "Second Crossbar...";
+ vc->dialog_func[vc->dialog_count] = vc_ShowSecondCrossbarDialog;
+ vc->dialog_count++;
+ pSpec->Release();
+ }
+
+ pX2->Release();
+ }
+
+ pX->Release();
+ }
+
+ IAMTVTuner* pTVT = vc_GetTVTuner(vc);
+ if (pTVT)
+ {
+ pSpec = vc_GetPropertyPages((IUnknown*)pTVT);
+ if (pSpec)
+ {
+ vc->dialog_desc[vc->dialog_count] = "TV Tuner...";
+ vc->dialog_func[vc->dialog_count] = vc_ShowTVTunerDialog;
+ vc->dialog_count++;
+ pSpec->Release();
+ }
+
+ pTVT->Release();
+ }
+}
+
+int imVideoCaptureDialogCount(imVideoCapture* vc)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ return vc->dialog_count;
+}
+
+const char* imVideoCaptureDialogDesc(imVideoCapture* vc, int dialog)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ if (dialog >= vc->dialog_count)
+ return NULL;
+
+ return vc->dialog_desc[dialog];
+}
+
+int imVideoCaptureShowDialog(imVideoCapture* vc, int dialog, void* parent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ if (dialog >= vc->dialog_count)
+ return 0;
+
+ return vc->dialog_func[dialog](vc, (HWND)parent);
+}
+
+int imVideoCaptureSetInOut(imVideoCapture* vc, int input, int output, int cross)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ IAMCrossbar* pX = vc_GetCrossBar(vc);
+ if (pX)
+ {
+ HRESULT hr = S_FALSE;
+
+ if (cross == 1)
+ hr = pX->Route(output, input);
+ else
+ {
+ IAMCrossbar* pX2 = vc_GetSecondCrossBar(vc, pX);
+ if (pX2)
+ {
+ hr = pX2->Route(output, input);
+ pX2->Release();
+ }
+ }
+
+ pX->Release();
+ if (hr == S_OK)
+ return 1;
+ }
+
+ return 0;
+}
+
+/**************************************************************************
+ Attributes
+***************************************************************************/
+
+
+static float vc_Value2Percent(long Min, long Max, long Val)
+{
+ return ((Val - Min)*100.0f)/((float)(Max - Min));
+}
+
+static long vc_Percent2Value(long Min, long Max, long Step, float Per)
+{
+ long Val = (long)((Per/100.)*(Max - Min) + Min);
+ if (Step == 1)
+ return Val;
+
+ long num_step = (Val - Min + Step-1) / Step;
+ return num_step*Step + Min;
+}
+
+static IAMVideoProcAmp* vc_InitVideoProcAmp(IBaseFilter* capture_filter, IAMVideoProcAmp* *video_prop)
+{
+ if (*video_prop)
+ return *video_prop;
+
+ HRESULT hr = capture_filter->QueryInterface(IID_IAMVideoProcAmp, (void**)video_prop);
+ if (FAILED(hr))
+ return NULL;
+
+ return *video_prop;
+}
+
+static int vc_SetVideoProcAmpProperty(IBaseFilter* capture_filter, IAMVideoProcAmp* *video_prop, long property, float percent)
+{
+ IAMVideoProcAmp *pProp = vc_InitVideoProcAmp(capture_filter, video_prop);
+ if (!pProp) return 0;
+ HRESULT hr;
+ VideoProcAmpProperty prop = (VideoProcAmpProperty)property;
+ long Min, Max, Step, Default, Flags;
+ hr = pProp->GetRange(prop, &Min, &Max, &Step, &Default, &Flags);
+ hr = pProp->Set(prop, vc_Percent2Value(Min, Max, Step, percent), VideoProcAmp_Flags_Manual);
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static int vc_GetVideoProcAmpProperty(IBaseFilter* capture_filter, IAMVideoProcAmp* *video_prop, long property, float *percent)
+{
+ IAMVideoProcAmp *pProp = vc_InitVideoProcAmp(capture_filter, video_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ VideoProcAmpProperty prop = (VideoProcAmpProperty)property;
+ long Min, Max, Step, Default, Flags, Val;
+ hr = pProp->GetRange(prop, &Min, &Max, &Step, &Default, &Flags);
+ hr = pProp->Get(prop, &Val, &Flags);
+
+ if (FAILED(hr)) return 0;
+ *percent = vc_Value2Percent(Min, Max, Val);
+ return 1;
+}
+
+static int vc_ResetVideoProcAmpProperty(IBaseFilter* capture_filter, IAMVideoProcAmp* *video_prop, long property, int fauto)
+{
+ IAMVideoProcAmp *pProp = vc_InitVideoProcAmp(capture_filter, video_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ VideoProcAmpProperty prop = (VideoProcAmpProperty)property;
+ long Min, Max, Step, Default, Flags;
+ hr = pProp->GetRange(prop, &Min, &Max, &Step, &Default, &Flags);
+
+ if (fauto && (Flags & VideoProcAmp_Flags_Auto))
+ hr = pProp->Set(prop, Default, VideoProcAmp_Flags_Auto);
+ else
+ hr = pProp->Set(prop, Default, VideoProcAmp_Flags_Manual);
+
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static IAMCameraControl* vc_InitCameraControl(IBaseFilter* capture_filter, IAMCameraControl* *camera_prop)
+{
+ if (*camera_prop)
+ return *camera_prop;
+
+ HRESULT hr = capture_filter->QueryInterface(IID_IAMCameraControl, (void**)camera_prop);
+ if (FAILED(hr))
+ return NULL;
+
+ return *camera_prop;
+}
+
+static int vc_SetCameraControlProperty(IBaseFilter* capture_filter, IAMCameraControl* *camera_prop, long property, float percent)
+{
+ IAMCameraControl *pProp = vc_InitCameraControl(capture_filter, camera_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ CameraControlProperty prop = (CameraControlProperty)property;
+ long Min, Max, Step, Default, Flags;
+ hr = pProp->GetRange(prop, &Min, &Max, &Step, &Default, &Flags);
+ hr = pProp->Set(prop, vc_Percent2Value(Min, Max, Step, percent), CameraControl_Flags_Manual);
+
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static int vc_GetCameraControlProperty(IBaseFilter* capture_filter, IAMCameraControl* *camera_prop, long property, float *percent)
+{
+ IAMCameraControl *pProp = vc_InitCameraControl(capture_filter, camera_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ CameraControlProperty prop = (CameraControlProperty)property;
+ long Min, Max, Step, Default, Flags, Val;
+ hr = pProp->GetRange(prop, &Min, &Max, &Step, &Default, &Flags);
+ hr = pProp->Get(prop, &Val, &Flags);
+
+ if (FAILED(hr)) return 0;
+ *percent = vc_Value2Percent(Min, Max, Val);
+ return 1;
+}
+
+static int vc_ResetCameraControlProperty(IBaseFilter* capture_filter, IAMCameraControl* *camera_prop, long property, int fauto)
+{
+ IAMCameraControl *pProp = vc_InitCameraControl(capture_filter, camera_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ CameraControlProperty prop = (CameraControlProperty)property;
+ long Min, Max, Step, Default, Flags;
+ hr = pProp->GetRange(prop, &Min, &Max, &Step, &Default, &Flags);
+
+ if (fauto && (Flags & CameraControl_Flags_Auto))
+ hr = pProp->Set(prop, Default, CameraControl_Flags_Auto);
+ else
+ hr = pProp->Set(prop, Default, CameraControl_Flags_Manual);
+
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static IAMVideoControl* vc_InitVideoControl(IBaseFilter* capture_filter, IAMVideoControl* *video_prop)
+{
+ if (*video_prop)
+ return *video_prop;
+
+ HRESULT hr = capture_filter->QueryInterface(IID_IAMVideoControl, (void**)video_prop);
+ if (FAILED(hr))
+ return NULL;
+
+ return *video_prop;
+}
+
+static int vc_SetVideoControlProperty(IBaseFilter* capture_filter, IAMVideoControl* *video_prop, long property, float percent)
+{
+ IAMVideoControl *pProp = vc_InitVideoControl(capture_filter, video_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ IPin *pOutPin = vc_GetPin(capture_filter, PINDIR_OUTPUT);
+ long Mode;
+ hr = pProp->GetMode(pOutPin, &Mode);
+ if (percent)
+ Mode = Mode | property;
+ else
+ Mode = Mode & ~property;
+ hr = pProp->SetMode(pOutPin, Mode);
+ pOutPin->Release();
+
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static int vc_GetVideoControlProperty(IBaseFilter* capture_filter, IAMVideoControl* *video_prop, long property, float *percent)
+{
+ IAMVideoControl *pProp = vc_InitVideoControl(capture_filter, video_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ long Mode;
+ IPin *pOutPin = vc_GetPin(capture_filter, PINDIR_OUTPUT);
+ hr = pProp->GetMode(pOutPin, &Mode);
+ pOutPin->Release();
+
+ if (FAILED(hr)) return 0;
+ if (Mode & property)
+ *percent = 100.;
+ else
+ *percent = 0.;
+ return 1;
+}
+
+static int vc_ResetVideoControlProperty(IBaseFilter* capture_filter, IAMVideoControl* *video_prop, long property, int fauto)
+{
+ IAMVideoControl *pProp = vc_InitVideoControl(capture_filter, video_prop);
+ if (!pProp) return 0;
+
+ HRESULT hr;
+ long Mode;
+ IPin *pOutPin = vc_GetPin(capture_filter, PINDIR_OUTPUT);
+ hr = pProp->GetMode(pOutPin, &Mode);
+ if (Mode & property)
+ Mode = Mode & ~property;
+ else
+ Mode = Mode | property;
+ hr = pProp->SetMode(pOutPin, Mode);
+ pOutPin->Release();
+
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static long vc_AnalogFormat[19] =
+{
+ AnalogVideo_NTSC_M,
+ AnalogVideo_NTSC_M_J,
+ AnalogVideo_NTSC_433,
+ AnalogVideo_PAL_B,
+ AnalogVideo_PAL_D,
+ AnalogVideo_PAL_H,
+ AnalogVideo_PAL_I,
+ AnalogVideo_PAL_M,
+ AnalogVideo_PAL_N,
+ AnalogVideo_PAL_60,
+ AnalogVideo_SECAM_B,
+ AnalogVideo_SECAM_D,
+ AnalogVideo_SECAM_G,
+ AnalogVideo_SECAM_H,
+ AnalogVideo_SECAM_K,
+ AnalogVideo_SECAM_K1,
+ AnalogVideo_SECAM_L,
+ AnalogVideo_SECAM_L1,
+ AnalogVideo_PAL_N_COMBO
+};
+
+static int vc_SetAnalogFormat(IBaseFilter* capture_filter, float percent)
+{
+ IAMAnalogVideoDecoder* video_decoder = NULL;
+ HRESULT hr = capture_filter->QueryInterface(IID_IAMAnalogVideoDecoder, (void**)video_decoder);
+ if (FAILED(hr))
+ return 0;
+
+ hr = video_decoder->put_TVFormat(vc_AnalogFormat[(int)percent]);
+ video_decoder->Release();
+
+ if (FAILED(hr)) return 0;
+ return 1;
+}
+
+static int vc_GetAnalogFormat(IBaseFilter* capture_filter, float *percent)
+{
+ IAMAnalogVideoDecoder* video_decoder = NULL;
+ HRESULT hr = capture_filter->QueryInterface(IID_IAMAnalogVideoDecoder, (void**)video_decoder);
+ if (FAILED(hr))
+ return 0;
+
+ long format;
+ hr = video_decoder->get_TVFormat(&format);
+ video_decoder->Release();
+
+ if (FAILED(hr)) return 0;
+ for (int i = 0; i < 19; i++)
+ {
+ if (vc_AnalogFormat[i] == format)
+ {
+ *percent = (float)i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#define VC_HASH_SIZE 101
+#define VC_HASH_MULTIPLIER 31
+
+/** Unique Hash index for a key
+ * We use the hash function described in "The Pratice of Programming" of Kernighan & Pike. */
+static int vc_HashIndex(const char *key, int hash_size)
+{
+ unsigned short hash = 0;
+ const unsigned char *p_key = (const unsigned char*)key;
+
+ for(; *p_key; p_key++)
+ hash = hash*VC_HASH_MULTIPLIER + *p_key;
+
+ return hash % hash_size;
+}
+
+#define VC_CAMERASHIFT 20
+#define VC_VIDEOSHIFT 40
+#define VC_ANALOGSHIFT 60
+
+static long vc_Attrib2Property(const char* attrib)
+{
+ static long prop_table[VC_HASH_SIZE];
+ static int first = 1;
+ if (first)
+ {
+ memset(prop_table, 0, VC_HASH_SIZE*sizeof(long));
+ prop_table[vc_HashIndex("CameraPanAngle", VC_HASH_SIZE)] = (long)CameraControl_Pan + VC_CAMERASHIFT + 1;
+ prop_table[vc_HashIndex("CameraTiltAngle", VC_HASH_SIZE)] = (long)CameraControl_Tilt + VC_CAMERASHIFT + 1;
+ prop_table[vc_HashIndex("CameraRollAngle", VC_HASH_SIZE)] = (long)CameraControl_Roll + VC_CAMERASHIFT + 1;
+ prop_table[vc_HashIndex("CameraLensZoom", VC_HASH_SIZE)] = (long)CameraControl_Zoom + VC_CAMERASHIFT + 1;
+ prop_table[vc_HashIndex("CameraExposure", VC_HASH_SIZE)] = (long)CameraControl_Exposure + VC_CAMERASHIFT + 1;
+ prop_table[vc_HashIndex("CameraIris", VC_HASH_SIZE)] = (long)CameraControl_Iris + VC_CAMERASHIFT + 1;
+ prop_table[vc_HashIndex("CameraFocus", VC_HASH_SIZE)] = (long)CameraControl_Focus + VC_CAMERASHIFT + 1;
+ prop_table[vc_HashIndex("VideoBrightness", VC_HASH_SIZE)] = (long)VideoProcAmp_Brightness + 1;
+ prop_table[vc_HashIndex("VideoContrast", VC_HASH_SIZE)] = (long)VideoProcAmp_Contrast + 1;
+ prop_table[vc_HashIndex("VideoHue", VC_HASH_SIZE)] = (long)VideoProcAmp_Hue + 1;
+ prop_table[vc_HashIndex("VideoSaturation", VC_HASH_SIZE)] = (long)VideoProcAmp_Saturation + 1;
+ prop_table[vc_HashIndex("VideoSharpness", VC_HASH_SIZE)] = (long)VideoProcAmp_Sharpness + 1;
+ prop_table[vc_HashIndex("VideoGamma", VC_HASH_SIZE)] = (long)VideoProcAmp_Gamma + 1;
+ prop_table[vc_HashIndex("VideoColorEnable", VC_HASH_SIZE)] = (long)VideoProcAmp_ColorEnable + 1;
+ prop_table[vc_HashIndex("VideoWhiteBalance", VC_HASH_SIZE)] = (long)VideoProcAmp_WhiteBalance + 1;
+ prop_table[vc_HashIndex("VideoBacklightCompensation", VC_HASH_SIZE)] = (long)VideoProcAmp_BacklightCompensation + 1;
+ prop_table[vc_HashIndex("VideoGain", VC_HASH_SIZE)] = (long)VideoProcAmp_Gain + 1;
+ prop_table[vc_HashIndex("FlipHorizontal", VC_HASH_SIZE)] = (long)VideoControlFlag_FlipHorizontal + VC_VIDEOSHIFT + 1;
+ prop_table[vc_HashIndex("FlipVertical", VC_HASH_SIZE)] = (long)VideoControlFlag_FlipVertical + VC_VIDEOSHIFT + 1;
+ prop_table[vc_HashIndex("AnalogFormat", VC_HASH_SIZE)] = (long)0 + VC_ANALOGSHIFT + 1;
+ first = 0;
+ }
+ long prop = prop_table[vc_HashIndex(attrib, VC_HASH_SIZE)];
+ if (!prop)
+ return 0;
+ return prop-1;
+}
+
+int imVideoCaptureSetAttribute(imVideoCapture* vc, const char* attrib, float percent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ long property = vc_Attrib2Property(attrib);
+ if (property == -1) return 0;
+ if (property < VC_CAMERASHIFT)
+ return vc_SetVideoProcAmpProperty(vc->capture_filter, &vc->video_prop, property, percent);
+ else if (property < VC_VIDEOSHIFT)
+ return vc_SetCameraControlProperty(vc->capture_filter, &vc->camera_prop, property-VC_CAMERASHIFT, percent);
+ else if (property < VC_ANALOGSHIFT)
+ return vc_SetVideoControlProperty(vc->capture_filter, &vc->videoctrl_prop, property-VC_VIDEOSHIFT, percent);
+ else
+ return vc_SetAnalogFormat(vc->capture_filter, percent);
+}
+
+int imVideoCaptureGetAttribute(imVideoCapture* vc, const char* attrib, float *percent)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ long property = vc_Attrib2Property(attrib);
+ if (property == -1) return 0;
+ if (property < VC_CAMERASHIFT)
+ return vc_GetVideoProcAmpProperty(vc->capture_filter, &vc->video_prop, property, percent);
+ else if (property < VC_VIDEOSHIFT)
+ return vc_GetCameraControlProperty(vc->capture_filter, &vc->camera_prop, property-VC_CAMERASHIFT, percent);
+ else if (property < VC_ANALOGSHIFT)
+ return vc_GetVideoControlProperty(vc->capture_filter, &vc->videoctrl_prop, property-VC_VIDEOSHIFT, percent);
+ else
+ return vc_GetAnalogFormat(vc->capture_filter, percent);
+}
+
+int imVideoCaptureResetAttribute(imVideoCapture* vc, const char* attrib, int fauto)
+{
+ assert(vc);
+ assert(vc->device != -1);
+
+ long property = vc_Attrib2Property(attrib);
+ if (property == -1) return 0;
+ if (property < VC_CAMERASHIFT)
+ return vc_ResetVideoProcAmpProperty(vc->capture_filter, &vc->video_prop, property, fauto);
+ else if (property < VC_VIDEOSHIFT)
+ return vc_ResetCameraControlProperty(vc->capture_filter, &vc->camera_prop, property-VC_CAMERASHIFT, fauto);
+ else if (property < VC_ANALOGSHIFT)
+ return vc_ResetVideoControlProperty(vc->capture_filter, &vc->videoctrl_prop, property-VC_VIDEOSHIFT, fauto);
+ return 0;
+}
+
+const char** imVideoCaptureGetAttributeList(imVideoCapture* vc, int *num_attrib)
+{
+#define VC_VIDEOPROC_MAX 10
+#define VC_CAMERACONTROL_MAX 7
+#define VC_VIDEOCONTROL_MAX 2
+#define VC_VIDEODECODER_MAX 1
+#define VC_NUM_ATTRIB_MAX (VC_VIDEOPROC_MAX+VC_CAMERACONTROL_MAX+VC_VIDEOCONTROL_MAX+VC_VIDEODECODER_MAX)
+ static char* attrib_list[VC_NUM_ATTRIB_MAX];
+ static char* all_attrib_list[VC_NUM_ATTRIB_MAX] =
+ { //Pre-calculated Hash Index:
+ "VideoBrightness", // (97)
+ "VideoContrast", // (80)
+ "VideoHue", // (98)
+ "VideoSaturation", // (4)
+ "VideoSharpness", // (56)
+ "VideoGamma", // (67)
+ "VideoColorEnable", // (91)
+ "VideoWhiteBalance", // (26)
+ "VideoBacklightCompensation", // (50)
+ "VideoGain", // (36)
+ "CameraPanAngle", // (64)
+ "CameraTiltAngle", // (54)
+ "CameraRollAngle", // (85)
+ "CameraLensZoom", // (57)
+ "CameraExposure", // (84)
+ "CameraIris", // (20)
+ "CameraFocus", // (62)
+ "FlipHorizontal", // (21)
+ "FlipVertical", // (28)
+ "AnalogFormat"}; // (89)
+
+ int i;
+ *num_attrib = 0;
+
+ IAMVideoProcAmp *video_prop;
+ HRESULT hr = vc->capture_filter->QueryInterface(IID_IAMVideoProcAmp, (void**)&video_prop);
+ if (SUCCEEDED(hr))
+ {
+ for (i = 0; i < VC_VIDEOPROC_MAX; i++)
+ attrib_list[i] = all_attrib_list[i];
+ *num_attrib = VC_VIDEOPROC_MAX;
+ video_prop->Release();
+ }
+
+ IAMCameraControl *camera_prop;
+ hr = vc->capture_filter->QueryInterface(IID_IAMCameraControl, (void**)&camera_prop);
+ if (SUCCEEDED(hr))
+ {
+ for (i = 0; i < VC_CAMERACONTROL_MAX; i++)
+ attrib_list[i+*num_attrib] = all_attrib_list[i+VC_VIDEOPROC_MAX];
+ *num_attrib += VC_CAMERACONTROL_MAX;
+ camera_prop->Release();
+ }
+
+ IAMVideoControl* video_ctrl;
+ hr = vc->capture_filter->QueryInterface(IID_IAMVideoControl, (void**)&video_ctrl);
+ if (SUCCEEDED(hr))
+ {
+ for (i = 0; i < VC_VIDEOCONTROL_MAX; i++)
+ attrib_list[i+*num_attrib] = all_attrib_list[i+VC_VIDEOPROC_MAX+VC_CAMERACONTROL_MAX];
+ *num_attrib += VC_VIDEOCONTROL_MAX;
+ video_ctrl->Release();
+ }
+
+ IAMAnalogVideoDecoder* video_decoder = NULL;
+ hr = vc->capture_filter->QueryInterface(IID_IAMAnalogVideoDecoder, (void**)&video_decoder);
+ if (SUCCEEDED(hr))
+ {
+ for (i = 0; i < VC_VIDEODECODER_MAX; i++)
+ attrib_list[i+*num_attrib] = all_attrib_list[i+VC_VIDEOPROC_MAX+VC_CAMERACONTROL_MAX+VC_VIDEOCONTROL_MAX];
+ *num_attrib += VC_VIDEODECODER_MAX;
+ video_decoder->Release();
+ }
+
+ return (const char**)attrib_list;
+}
+
+//VIDEOINFOHEADER
+// AvgTimePerFrame
diff --git a/im/src/im_colorhsi.cpp b/im/src/im_colorhsi.cpp
new file mode 100755
index 0000000..953bb2c
--- /dev/null
+++ b/im/src/im_colorhsi.cpp
@@ -0,0 +1,265 @@
+/** \file
+ * \brief HSI Color Manipulation
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_colorhsi.cpp,v 1.2 2008/11/18 13:15:46 scuri Exp $
+ */
+
+
+#include <math.h>
+
+#include "im_colorhsi.h"
+#include "im_color.h"
+
+static const float rad60 = 1.0471975f;
+static const float rad120 = 2.0943951f;
+static const float rad180 = 3.1415926f;
+static const float rad240 = 4.1887902f;
+static const float rad300 = 5.2359877f;
+static const float rad360 = 6.2831853f;
+static const float sqrt3 = 1.7320508f;
+static const float rad2deg = 57.2957795131f;
+
+
+static double iColorNormHue(double H)
+{
+ while (H < 0.0)
+ H += rad360;
+
+ if (H > rad360)
+ H = fmod(H, (double)rad360);
+
+ return H;
+}
+
+/**********************************/
+/* HSI MAX S */
+/**********************************/
+
+static void iColorSmax01(float h, float hr, float hb, float hg, float *h0, float *h1)
+{
+ if (h < rad60)
+ {
+ *h0 = hb;
+ *h1 = hr;
+ }
+ else if (h < rad120)
+ {
+ *h0 = hb;
+ *h1 = hg;
+ }
+ else if (h < rad180)
+ {
+ *h0 = hr;
+ *h1 = hg;
+ }
+ else if (h < rad240)
+ {
+ *h0 = hr;
+ *h1 = hb;
+ }
+ else if (h < rad300)
+ {
+ *h0 = hg;
+ *h1 = hb;
+ }
+ else
+ {
+ *h0 = hg;
+ *h1 = hr;
+ }
+}
+
+static float iColorHSI_Smax(float h, double cosH, double sinH, float i)
+{
+ float hr, hb, hg, imax, h0, h1;
+
+ /* i here is normalized between 0-1 */
+
+ if (i == 0 || i == 1)
+ return 0.0f;
+
+ /* Making r=0, g=0, b=0, r=1, g=1 or b=1 in the parametric equations and
+ writting s in function of H and I. */
+
+ hr = (float)(cosH / 1.5);
+ hg = (float)((-cosH + sinH*sqrt3)/ 3.0);
+ hb = (float)((-cosH - sinH*sqrt3)/ 3.0);
+
+ /* at bottom */
+ if (i <= 1.0f/3.0f)
+ {
+ /* face B=0 */
+ if (h < rad120)
+ return -i/hb;
+
+ /* face R=0 */
+ if (h < rad240)
+ return -i/hr;
+
+ /* face G=0 */
+ return -i/hg;
+ }
+
+ /* at top */
+ if (i >= 2.0f/3.0f)
+ {
+ /* face R=1 */
+ if (h < rad60 || h > rad300)
+ return (1-i)/hr;
+
+ /* face G=1 */
+ if (h < rad180)
+ return (1-i)/hg;
+
+ /* face B=1 */
+ return (1-i)/hb;
+ }
+
+ /* in the middle */
+
+ iColorSmax01(h, hr, hb, hg, &h0, &h1);
+
+ if (h == 0 || h == rad120 || h == rad240)
+ imax = 1.0f/3.0f;
+ else if (h == rad60 || h == rad180 || h == rad300)
+ imax = 2.0f/3.0f;
+ else
+ imax = h0 / (h0 - h1);
+
+ if (i < imax)
+ return -i/h0;
+ else
+ return (1-i)/h1;
+}
+
+float imColorHSI_ImaxS(float h, double cosH, double sinH)
+{
+ float i, h0, h1;
+ float hr, hb, hg;
+
+ if (h == 0 || h == rad120 || h == rad240)
+ return 1.0f/3.0f;
+
+ if (h == rad60 || h == rad180 || h == rad300)
+ return 2.0f/3.0f;
+
+ hr = (float)(cosH / 1.5f);
+ hg = (float)((-cosH + sinH*sqrt3)/ 3.0);
+ hb = (float)((-cosH - sinH*sqrt3)/ 3.0);
+
+ iColorSmax01(h, hr, hb, hg, &h0, &h1);
+
+ i = h0 / (h0 - h1);
+
+ return i;
+}
+
+/**********************************/
+/* RGB 2 HSI */
+/**********************************/
+
+void imColorRGB2HSI(float r, float g, float b, float *h, float *s, float *i)
+{
+ float v, u;
+ double H;
+
+ /* Parametric equations */
+ v = r - (g + b)/2;
+ u = (g - b) * (sqrt3/2);
+
+ *i = (r + g + b)/3; /* already normalized to 0-1 */
+ *s = (float)sqrt(v*v + u*u); /* s is between 0-1, it is linear in the cube and it is in u,v space. */
+
+ if (*s == 0)
+ *h = 360.0f; /* by definition */
+ else
+ {
+ H = atan2(u, v);
+ H = iColorNormHue(H);
+ *h = (float)(H * rad2deg);
+
+ /* must scale S from 0-Smax to 0-1 */
+ float Smax = iColorHSI_Smax((float)H, cos(H), sin(H), *i);
+ if (Smax == 0.0f)
+ *s = 0.0f;
+ else
+ {
+ if (*s > Smax) /* because of round problems when calculating s and Smax */
+ *s = Smax;
+ *s /= Smax;
+ }
+ }
+}
+
+void imColorRGB2HSIbyte(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *i)
+{
+ float fr = imColorReconstruct(r, (imbyte)255);
+ float fg = imColorReconstruct(g, (imbyte)255);
+ float fb = imColorReconstruct(b, (imbyte)255);
+
+ imColorRGB2HSI(fr, fg, fb, h, s, i);
+}
+
+/**********************************/
+/* HSI 2 RGB */
+/**********************************/
+
+void imColorHSI2RGB(float h, float s, float i, float *r, float *g, float *b)
+{
+ double cosH, sinH, H, v, u;
+
+ if (i < 0) i = 0;
+ else if (i > 1) i = 1;
+
+ if (s < 0) s = 0;
+ else if (s > 1) s = 1;
+
+ if (s == 0.0f || i == 1.0f || i == 0.0f || (int)h == 360)
+ {
+ *r = i;
+ *g = i;
+ *b = i;
+ return;
+ }
+
+ H = h/rad2deg;
+ H = iColorNormHue(H);
+
+ cosH = cos(H);
+ sinH = sin(H);
+
+ /* must scale S from 0-1 to 0-Smax */
+ float Smax = iColorHSI_Smax((float)H, cosH, sinH, i);
+ s *= Smax;
+ if (s > 1.0f) /* because of round problems when calculating s and Smax */
+ s = 1.0f;
+
+ v = s * cosH;
+ u = s * sinH;
+
+ /* Inverse of the Parametric equations, using i normalized to 0-1 */
+ *r = (float)(i + v/1.5);
+ *g = (float)(i - (v - u*sqrt3)/3.0);
+ *b = (float)(i - (v + u*sqrt3)/3.0);
+
+ /* fix round errors */
+ if (*r < 0) *r = 0;
+ if (*g < 0) *g = 0;
+ if (*b < 0) *b = 0;
+
+ if (*r > 1) *r = 1.0f;
+ if (*g > 1) *g = 1.0f;
+ if (*b > 1) *b = 1.0f;
+}
+
+void imColorHSI2RGBbyte(float h, float s, float i, unsigned char *r, unsigned char *g, unsigned char *b)
+{
+ float fr, fg, fb;
+
+ imColorHSI2RGB(h, s, i, &fr, &fg, &fb);
+
+ *r = imColorQuantize(fr, (imbyte)255);
+ *g = imColorQuantize(fg, (imbyte)255);
+ *b = imColorQuantize(fb, (imbyte)255);
+}
diff --git a/im/src/im_colormode.cpp b/im/src/im_colormode.cpp
new file mode 100755
index 0000000..2a99183
--- /dev/null
+++ b/im/src/im_colormode.cpp
@@ -0,0 +1,87 @@
+/** \file
+ * \brief Color Mode Utilities
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_colormode.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+
+#include "im.h"
+#include "im_util.h"
+
+const char* imColorModeSpaceName(int color_mode)
+{
+ int color_space = imColorModeSpace(color_mode);
+ switch (color_space)
+ {
+ case IM_RGB: return "RGB";
+ case IM_MAP: return "Map";
+ case IM_GRAY: return "Gray";
+ case IM_BINARY: return "Binary";
+ case IM_CMYK: return "CMYK";
+ case IM_YCBCR: return "Y'CbCr";
+ case IM_LAB: return "CIE L*a*b*";
+ case IM_LUV: return "CIE L*u*v*";
+ case IM_XYZ: return "CIE XYZ";
+ }
+
+ return NULL;
+}
+
+int imColorModeDepth(int color_mode)
+{
+ int depth = 0;
+
+ int color_space = imColorModeSpace(color_mode);
+ switch (color_space)
+ {
+ case IM_GRAY:
+ case IM_BINARY:
+ case IM_MAP:
+ depth = 1;
+ break;
+ case IM_CMYK:
+ depth = 4;
+ break;
+ default:
+ depth = 3;
+ break;
+ }
+
+ if (imColorModeHasAlpha(color_mode))
+ depth++;
+
+ return depth;
+}
+
+int imColorModeToBitmap(int color_mode)
+{
+ int color_space = imColorModeSpace(color_mode);
+ switch (color_space)
+ {
+ case IM_BINARY:
+ case IM_GRAY:
+ case IM_MAP:
+ return color_space;
+ default:
+ return IM_RGB;
+ }
+}
+
+int imColorModeIsBitmap(int color_mode, int data_type)
+{
+ if (imColorModeSpace(color_mode) == IM_BINARY ||
+ imColorModeSpace(color_mode) == IM_MAP)
+ return 1;
+
+ if ((imColorModeSpace(color_mode) == IM_RGB ||
+ imColorModeSpace(color_mode) == IM_GRAY) &&
+ (data_type == IM_BYTE))
+ return 1;
+
+ return 0;
+}
diff --git a/im/src/im_colorutil.cpp b/im/src/im_colorutil.cpp
new file mode 100755
index 0000000..9e96c65
--- /dev/null
+++ b/im/src/im_colorutil.cpp
@@ -0,0 +1,27 @@
+/** \file
+ * \brief Color Utilities
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_colorutil.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+
+#include "im.h"
+#include "im_util.h"
+
+long imColorEncode(unsigned char Red, unsigned char Green, unsigned char Blue)
+{
+ return (((long)Red) << 16) | (((long)Green) << 8) | ((long)Blue);
+}
+
+void imColorDecode(unsigned char* Red, unsigned char* Green, unsigned char* Blue, long Color)
+{
+ if (Red) *Red = (imbyte)(Color >> 16);
+ if (Green) *Green = (imbyte)(Color >> 8);
+ if (Blue) *Blue = (imbyte)Color;
+}
+
diff --git a/im/src/im_convertbitmap.cpp b/im/src/im_convertbitmap.cpp
new file mode 100755
index 0000000..a4f6b70
--- /dev/null
+++ b/im/src/im_convertbitmap.cpp
@@ -0,0 +1,284 @@
+/** \file
+ * \brief Image Conversion
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_convertbitmap.cpp,v 1.3 2009/08/18 02:23:33 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_util.h"
+#include "im_complex.h"
+#include "im_image.h"
+#include "im_convert.h"
+#include "im_counter.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <memory.h>
+
+int imConvertToBitmap(const imImage* src_image, imImage* dst_image, int cpx2real, float gamma, int abssolute, int cast_mode)
+{
+ assert(src_image);
+ assert(dst_image);
+
+ if (!imImageMatchSize(src_image, dst_image) || !imImageIsBitmap(dst_image))
+ return IM_ERR_DATA;
+
+ int counter = imCounterBegin("Building Bitmap");
+
+ int ret;
+ if (src_image->data_type == IM_BYTE)
+ {
+ // NO data type conversion, only color mode conversion
+ ret = imConvertColorSpace(src_image, dst_image);
+ }
+ else
+ {
+ if (src_image->color_space == IM_RGB ||
+ src_image->color_space == IM_GRAY)
+ {
+ // data type conversion, but NO color mode conversion
+ ret = imConvertDataType(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode);
+ }
+ else
+ {
+ // data type conversion AND color mode conversion
+ imImage* temp_image = imImageCreate(src_image->width, src_image->height, dst_image->color_space, src_image->data_type);
+ if (!temp_image)
+ ret = IM_ERR_MEM;
+ else
+ {
+ // first convert color_mode in the bigger precision
+ ret = imConvertColorSpace(src_image, temp_image);
+ if (ret == IM_ERR_NONE)
+ {
+ // second just convert data type
+ ret = imConvertDataType(temp_image, dst_image, cpx2real, gamma, abssolute, cast_mode);
+ }
+ imImageDestroy(temp_image);
+ }
+ }
+ }
+
+ imCounterEnd(counter);
+ return ret;
+}
+
+
+template <class T>
+void iDoChangePacking(const T* src_data, T* dst_data, int width, int height, int depth,
+ int src_is_packed)
+{
+ int count = width*height;
+ if (src_is_packed)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ for (int d = 0; d < depth; d++)
+ {
+ *(dst_data + d*count) = *src_data++;
+ }
+
+ dst_data++;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < count; i++)
+ {
+ for (int d = 0; d < depth; d++)
+ {
+ *dst_data++ = *(src_data + d*count);
+ }
+
+ src_data++;
+ }
+ }
+}
+
+void imConvertPacking(const void* src_data, void* dst_data, int width, int height, int depth,
+ int data_type, int src_is_packed)
+{
+ switch(data_type)
+ {
+ case IM_BYTE:
+ iDoChangePacking((const imbyte*)src_data, (imbyte*)dst_data, width, height, depth, src_is_packed);
+ break;
+ case IM_USHORT:
+ iDoChangePacking((const imushort*)src_data, (imushort*)dst_data, width, height, depth, src_is_packed);
+ break;
+ case IM_INT:
+ iDoChangePacking((const int*)src_data, (int*)dst_data, width, height, depth, src_is_packed);
+ break;
+ case IM_FLOAT:
+ iDoChangePacking((const float*)src_data, (float*)dst_data, width, height, depth, src_is_packed);
+ break;
+ case IM_CFLOAT:
+ iDoChangePacking((const imcfloat*)src_data, (imcfloat*)dst_data, width, height, depth, src_is_packed);
+ break;
+ }
+}
+
+static void iImageMakeGray(imbyte *map, int count, int step)
+{
+ for(int i = 0; i < count; i++)
+ {
+ if (*map)
+ *map = 255;
+ map += step;
+ }
+}
+
+static void iImageGLCopyMapAlpha(imbyte *map, imbyte *gldata, int depth, int count)
+{
+ /* gldata can be GL_RGBA or GL_LUMINANCE_ALPHA */
+ gldata += depth-1; /* position at first alpha */
+ for(int i = 0; i < count; i++)
+ {
+ *gldata = *map;
+ map++;
+ gldata += depth; /* skip to next alpha */
+ }
+}
+
+static void iImageGLSetTranspColor(imbyte *gldata, int count, imbyte r, imbyte g, imbyte b)
+{
+ /* gldata is GL_RGBA */
+ for(int i = 0; i < count; i++)
+ {
+ if (*(gldata+0) == r &&
+ *(gldata+1) == g &&
+ *(gldata+2) == b)
+ *(gldata+3) = 0; /* transparent */
+ else
+ *(gldata+3) = 255; /* opaque */
+ gldata += 4;
+ }
+}
+
+static void iImageGLSetTranspMap(imbyte *map, imbyte *gldata, int count, imbyte *transp_map, int transp_count)
+{
+ /* gldata is GL_RGBA */
+ gldata += 3; /* position at first alpha */
+ for(int i = 0; i < count; i++)
+ {
+ if (*map < transp_count)
+ *gldata = transp_map[*map];
+ else
+ *gldata = 255; /* opaque */
+
+ map++;
+ gldata += 4;
+ }
+}
+
+static void iImageGLSetTranspIndex(imbyte *map, imbyte *gldata, int depth, int count, imbyte index)
+{
+ /* gldata can be GL_RGBA or GL_LUMINANCE_ALPHA */
+ gldata += depth-1; /* position at first alpha */
+ for(int i = 0; i < count; i++)
+ {
+ if (*map == index)
+ *gldata = 0; /* full transparent */
+ else
+ *gldata = 255; /* opaque */
+
+ map++;
+ gldata += depth; /* skip to next alpha */
+ }
+}
+
+/* To avoid including gl.h */
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+
+void* imImageGetOpenGLData(const imImage* image, int *format)
+{
+ if (!imImageIsBitmap(image))
+ return NULL;
+
+ int transp_count;
+ imbyte* transp_index = (imbyte*)imImageGetAttribute(image, "TransparencyIndex", NULL, NULL);
+ imbyte* transp_map = (imbyte*)imImageGetAttribute(image, "TransparencyMap", NULL, &transp_count);
+ imbyte* transp_color = (imbyte*)imImageGetAttribute(image, "TransparencyColor", NULL, NULL);
+
+ int glformat;
+ switch(image->color_space)
+ {
+ case IM_MAP:
+ if (image->has_alpha || transp_map || transp_index)
+ glformat = GL_RGBA;
+ else
+ glformat = GL_RGB;
+ break;
+ case IM_RGB:
+ if (image->has_alpha || transp_color)
+ glformat = GL_RGBA;
+ else
+ glformat = GL_RGB;
+ break;
+ case IM_BINARY:
+ default: /* IM_GRAY */
+ if (image->has_alpha || transp_index)
+ glformat = GL_LUMINANCE_ALPHA;
+ else
+ glformat = GL_LUMINANCE;
+ break;
+ }
+
+ int depth;
+ switch (glformat)
+ {
+ case GL_RGB:
+ depth = 3;
+ break;
+ case GL_RGBA:
+ depth = 4;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ depth = 2;
+ break;
+ default: /* GL_LUMINANCE */
+ depth = 1;
+ break;
+ }
+
+ int size = image->count*depth;
+ imImageSetAttribute(image, "GLDATA", IM_BYTE, size, NULL);
+ imbyte* gldata = (imbyte*)imImageGetAttribute(image, "GLDATA", NULL, NULL);
+
+ if (image->color_space == IM_RGB)
+ {
+ if (image->has_alpha)
+ imConvertPacking(image->data[0], gldata, image->width, image->height, 4, IM_BYTE, 0);
+ else
+ {
+ imConvertPacking(image->data[0], gldata, image->width, image->height, 3, IM_BYTE, 0);
+
+ if (transp_color)
+ iImageGLSetTranspColor(gldata, image->count, *(transp_color+0), *(transp_color+1), *(transp_color+2));
+ }
+ }
+ else
+ {
+ memcpy(gldata, image->data[0], image->size);
+
+ if (image->color_space == IM_MAP)
+ imConvertMapToRGB(gldata, image->count, depth, 1, image->palette, image->palette_count);
+ else if (image->color_space == IM_BINARY)
+ iImageMakeGray(gldata, image->count, (glformat==GL_LUMINANCE_ALPHA)? 2: 1);
+
+ if (image->has_alpha)
+ iImageGLCopyMapAlpha((imbyte*)image->data[1], gldata, depth, image->count);
+ else if (transp_map)
+ iImageGLSetTranspMap((imbyte*)image->data[0], gldata, image->count, transp_map, transp_count);
+ else if (transp_index)
+ iImageGLSetTranspIndex((imbyte*)image->data[0], gldata, depth, image->count, *transp_index);
+ }
+
+ if (format) *format = glformat;
+ return gldata;
+}
+
diff --git a/im/src/im_convertcolor.cpp b/im/src/im_convertcolor.cpp
new file mode 100755
index 0000000..e68730f
--- /dev/null
+++ b/im/src/im_convertcolor.cpp
@@ -0,0 +1,985 @@
+/** \file
+ * \brief Image Conversion
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_convertcolor.cpp,v 1.3 2009/08/18 05:13:18 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_util.h"
+#include "im_complex.h"
+#include "im_image.h"
+#include "im_convert.h"
+#include "im_color.h"
+#include "im_counter.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <memory.h>
+
+void imConvertMapToRGB(unsigned char* data, int count, int depth, int packed, long* palette, int palette_count)
+{
+ int c, i, delta;
+ unsigned char r[256], g[256], b[256];
+ unsigned char *r_data, *g_data, *b_data;
+
+ unsigned char* src_data = data + count-1;
+ if (packed)
+ {
+ r_data = data + depth*(count-1);
+ g_data = r_data + 1;
+ b_data = r_data + 2;
+ delta = depth;
+ }
+ else
+ {
+ r_data = data + count - 1;
+ g_data = data + 2*count - 1;
+ b_data = data + 3*count - 1;
+ delta = 1;
+ }
+
+ for (c = 0; c < palette_count; c++)
+ imColorDecode(&r[c], &g[c], &b[c], palette[c]);
+
+ for (i = 0; i < count; i++)
+ {
+ int index = *src_data;
+ *r_data = r[index];
+ *g_data = g[index];
+ *b_data = b[index];
+
+ r_data -= delta;
+ g_data -= delta;
+ b_data -= delta;
+ src_data--;
+ }
+}
+
+static void iConvertSetTranspMap(imbyte *src_map, imbyte *dst_alpha, int count, imbyte *transp_map, int transp_count)
+{
+ for(int i = 0; i < count; i++)
+ {
+ if (*src_map < transp_count)
+ *dst_alpha = transp_map[*src_map];
+ else
+ *dst_alpha = 255; /* opaque */
+
+ src_map++;
+ dst_alpha++;
+ }
+}
+
+static void iConvertSetTranspIndex(imbyte *src_map, imbyte *dst_alpha, int count, imbyte index)
+{
+ for(int i = 0; i < count; i++)
+ {
+ if (*src_map == index)
+ *dst_alpha = 0; /* full transparent */
+ else
+ *dst_alpha = 255; /* opaque */
+
+ src_map++;
+ dst_alpha++;
+ }
+}
+
+static void iConvertSetTranspColor(imbyte **dst_data, int count, imbyte r, imbyte g, imbyte b)
+{
+ imbyte *pr = dst_data[0];
+ imbyte *pg = dst_data[1];
+ imbyte *pb = dst_data[2];
+ imbyte *pa = dst_data[3];
+
+ for(int i = 0; i < count; i++)
+ {
+ if (*pr == r &&
+ *pg == g &&
+ *pb == b)
+ *pa = 0; /* transparent */
+ else
+ *pa = 255; /* opaque */
+
+ pr++;
+ pg++;
+ pb++;
+ pa++;
+ }
+}
+
+// convert bin2gray and gray2bin
+inline void iConvertBinary(imbyte* map, int count, imbyte value)
+{
+ imbyte thres = (value == 255)? 1: 128;
+
+ // if gray2bin, check for invalid gray that already is binary
+ if (value != 255)
+ {
+ imbyte vmax = 0, *pmap = map;
+ for (int i = 0; i < count; i++)
+ {
+ if (*pmap > vmax)
+ vmax = *pmap;
+
+ pmap++;
+ }
+
+ if (vmax == 1)
+ thres = 1;
+ else
+ thres = vmax / 2;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ if (*map >= thres)
+ *map = value;
+ else
+ *map = 0;
+
+ map++;
+ }
+}
+
+static void iConvertMap2Gray(const imbyte* src_map, imbyte* dst_map, int count, const long* palette, const int palette_count)
+{
+ imbyte r, g, b;
+ imbyte remap[256];
+
+ for (int c = 0; c < palette_count; c++)
+ {
+ imColorDecode(&r, &g, &b, palette[c]);
+ remap[c] = imColorRGB2Luma(r, g, b);
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ *dst_map++ = remap[*src_map++];
+ }
+}
+
+static void iConvertMapToRGB(const imbyte* src_map, imbyte* red, imbyte* green, imbyte* blue, int count, const long* palette, const int palette_count)
+{
+ imbyte r[256], g[256], b[256];
+ for (int c = 0; c < palette_count; c++)
+ imColorDecode(&r[c], &g[c], &b[c], palette[c]);
+
+ for (int i = 0; i < count; i++)
+ {
+ int index = *src_map++;
+ *red++ = r[index];
+ *green++ = g[index];
+ *blue++ = b[index];
+ }
+}
+
+template <class T>
+int iDoConvert2Gray(int count, int data_type,
+ const T** src_data, int src_color_space, T** dst_data, int counter)
+{
+ int i;
+ T max;
+
+ const T* src_map0 = src_data[0];
+ const T* src_map1 = src_data[1];
+ const T* src_map2 = src_data[2];
+ const T* src_map3 = (src_color_space == IM_CMYK)? src_data[3]: 0;
+ T* dst_map = dst_data[0];
+
+ imCounterTotal(counter, count, "Converting To Gray...");
+
+ switch(src_color_space)
+ {
+ case IM_XYZ:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // scale to 0-1
+ float c1 = imColorReconstruct(*src_map1++, max); // use only Y component
+
+ // do gamma correction then scale back to 0-max
+ *dst_map++ = imColorQuantize(imColorTransfer2Nonlinear(c1), max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_CMYK:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ T r, g, b;
+ // result is still 0-max
+ imColorCMYK2RGB(*src_map0++, *src_map1++, *src_map2++, *src_map3++, r, g, b, max);
+ *dst_map++ = imColorRGB2Luma(r, g, b);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_RGB:
+ for (i = 0; i < count; i++)
+ {
+ *dst_map++ = imColorRGB2Luma(*src_map0++, *src_map1++, *src_map2++);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_LUV:
+ case IM_LAB:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+
+ float c0 = imColorReconstruct(*src_map0++, max); // scale to 0-1
+ c0 = imColorLightness2Luminance(c0); // do the convertion
+
+ // do gamma correction then scale back to 0-max
+ *dst_map++ = imColorQuantize(imColorTransfer2Nonlinear(c0), max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class T>
+int iDoConvert2RGB(int count, int data_type,
+ const T** src_data, int src_color_space, T** dst_data, int counter)
+{
+ int i;
+ T max, zero;
+
+ const T* src_map0 = src_data[0];
+ const T* src_map1 = src_data[1];
+ const T* src_map2 = src_data[2];
+ const T* src_map3 = (src_color_space == IM_CMYK)? src_data[3]: 0;
+ T* dst_map0 = dst_data[0];
+ T* dst_map1 = dst_data[1];
+ T* dst_map2 = dst_data[2];
+
+ imCounterTotal(counter, count, "Converting To RGB...");
+
+ switch(src_color_space)
+ {
+ case IM_XYZ:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+
+ // scale to 0-1
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max);
+ float c2 = imColorReconstruct(*src_map2++, max);
+
+ // result is still 0-1
+ imColorXYZ2RGB(c0, c1, c2,
+ c0, c1, c2, 1.0f);
+
+ // do gamma correction then scale back to 0-max
+ *dst_map0++ = imColorQuantize(imColorTransfer2Nonlinear(c0), max);
+ *dst_map1++ = imColorQuantize(imColorTransfer2Nonlinear(c1), max);
+ *dst_map2++ = imColorQuantize(imColorTransfer2Nonlinear(c2), max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_YCBCR:
+ max = (T)imColorMax(data_type);
+ zero = (T)imColorZero(data_type);
+ for (i = 0; i < count; i++)
+ {
+ imColorYCbCr2RGB(*src_map0++, *src_map1++, *src_map2++,
+ *dst_map0++, *dst_map1++, *dst_map2++, zero, max);
+ }
+ break;
+ case IM_CMYK:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // result is still 0-max
+ imColorCMYK2RGB(*src_map0++, *src_map1++, *src_map2++, *src_map3++,
+ *dst_map0++, *dst_map1++, *dst_map2++, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_LUV:
+ case IM_LAB:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+
+ // scale to 0-1 and -0.5/+0.5
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max) - 0.5f;
+ float c2 = imColorReconstruct(*src_map2++, max) - 0.5f;
+
+ if (src_color_space == IM_LUV)
+ imColorLuv2XYZ(c0, c1, c2, // conversion in-place
+ c0, c1, c2);
+ else
+ imColorLab2XYZ(c0, c1, c2, // conversion in-place
+ c0, c1, c2);
+
+ imColorXYZ2RGB(c0, c1, c2, // conversion in-place
+ c0, c1, c2, 1.0f);
+
+ // do gamma correction then scale back to 0-max
+ *dst_map0++ = imColorQuantize(imColorTransfer2Nonlinear(c0), max);
+ *dst_map1++ = imColorQuantize(imColorTransfer2Nonlinear(c1), max);
+ *dst_map2++ = imColorQuantize(imColorTransfer2Nonlinear(c2), max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class T>
+int iDoConvert2YCbCr(int count, int data_type,
+ const T** src_data, int src_color_space, T** dst_data, int counter)
+{
+ int i;
+ T zero;
+
+ const T* src_map0 = src_data[0];
+ const T* src_map1 = src_data[1];
+ const T* src_map2 = src_data[2];
+ T* dst_map0 = dst_data[0];
+ T* dst_map1 = dst_data[1];
+ T* dst_map2 = dst_data[2];
+
+ imCounterTotal(counter, count, "Converting To YCbCr...");
+
+ switch(src_color_space)
+ {
+ case IM_RGB:
+ zero = (T)imColorZero(data_type);
+ for (i = 0; i < count; i++)
+ {
+ imColorRGB2YCbCr(*src_map0++, *src_map1++, *src_map2++,
+ *dst_map0++, *dst_map1++, *dst_map2++, zero);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class T>
+int iDoConvert2XYZ(int count, int data_type,
+ const T** src_data, int src_color_space, T** dst_data, int counter)
+{
+ int i;
+ T max;
+
+ const T* src_map0 = src_data[0];
+ const T* src_map1 = (src_color_space == IM_GRAY)? 0: src_data[1];
+ const T* src_map2 = (src_color_space == IM_GRAY)? 0: src_data[2];
+ T* dst_map0 = dst_data[0];
+ T* dst_map1 = dst_data[1];
+ T* dst_map2 = dst_data[2];
+
+ imCounterTotal(counter, count, "Converting To XYZ...");
+
+ switch(src_color_space)
+ {
+ case IM_GRAY:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // scale to 0-1
+ float c0 = imColorReconstruct(*src_map0++, max);
+
+ // do gamma correction
+ c0 = imColorTransfer2Linear(c0);
+
+ // then scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0*0.9505f, max); // Compensate D65 white point
+ *dst_map1++ = imColorQuantize(c0, max);
+ *dst_map2++ = imColorQuantize(c0*1.0890f, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_RGB:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+
+ // scale to 0-1
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max);
+ float c2 = imColorReconstruct(*src_map2++, max);
+
+ // do gamma correction
+ c0 = imColorTransfer2Linear(c0);
+ c1 = imColorTransfer2Linear(c1);
+ c2 = imColorTransfer2Linear(c2);
+
+ // result is still 0-1
+ imColorRGB2XYZ(c0, c1, c2,
+ c0, c1, c2);
+
+ // then scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1, max);
+ *dst_map2++ = imColorQuantize(c2, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_LUV:
+ case IM_LAB:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+ // scale to 0-1 and -0.5/+0.5
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max) - 0.5f;
+ float c2 = imColorReconstruct(*src_map2++, max) - 0.5f;
+
+ if (src_color_space == IM_LUV)
+ imColorLuv2XYZ(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+ else
+ imColorLab2XYZ(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ // scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1, max);
+ *dst_map2++ = imColorQuantize(c2, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class T>
+int iDoConvert2Lab(int count, int data_type,
+ const T** src_data, int src_color_space, T** dst_data, int counter)
+{
+ int i;
+ T max;
+
+ const T* src_map0 = src_data[0];
+ const T* src_map1 = (src_color_space == IM_GRAY)? 0: src_data[1];
+ const T* src_map2 = (src_color_space == IM_GRAY)? 0: src_data[2];
+ T* dst_map0 = dst_data[0];
+ T* dst_map1 = dst_data[1];
+ T* dst_map2 = dst_data[2];
+
+ imCounterTotal(counter, count, "Converting To Lab...");
+
+ switch(src_color_space)
+ {
+ case IM_GRAY:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // scale to 0-1
+ float c0 = imColorReconstruct(*src_map0++, max);
+
+ // do gamma correction
+ c0 = imColorTransfer2Linear(c0);
+
+ // do conversion
+ c0 = imColorLuminance2Lightness(c0);
+
+ // then scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max); // update only the L component
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_RGB:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+
+ // scale to 0-1
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max);
+ float c2 = imColorReconstruct(*src_map2++, max);
+
+ // do gamma correction
+ c0 = imColorTransfer2Linear(c0);
+ c1 = imColorTransfer2Linear(c1);
+ c2 = imColorTransfer2Linear(c2);
+
+ imColorRGB2XYZ(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ imColorXYZ2Lab(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ // then scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1 + 0.5f, max);
+ *dst_map2++ = imColorQuantize(c2 + 0.5f, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_XYZ:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+ // scale to 0-1 and -0.5/+0.5
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max);
+ float c2 = imColorReconstruct(*src_map2++, max);
+
+ imColorXYZ2Lab(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ // scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1 + 0.5f, max);
+ *dst_map2++ = imColorQuantize(c2 + 0.5f, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_LUV:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+ // scale to 0-1 and -0.5/+0.5
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max) - 0.5f;
+ float c2 = imColorReconstruct(*src_map2++, max) - 0.5f;
+
+ imColorLuv2XYZ(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+ imColorXYZ2Lab(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ // scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1 + 0.5f, max);
+ *dst_map2++ = imColorQuantize(c2 + 0.5f, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class T>
+int iDoConvert2Luv(int count, int data_type,
+ const T** src_data, int src_color_space, T** dst_data, int counter)
+{
+ int i;
+ T max;
+
+ const T* src_map0 = src_data[0];
+ const T* src_map1 = (src_color_space == IM_GRAY)? 0: src_data[1];
+ const T* src_map2 = (src_color_space == IM_GRAY)? 0: src_data[2];
+ T* dst_map0 = dst_data[0];
+ T* dst_map1 = dst_data[1];
+ T* dst_map2 = dst_data[2];
+
+ imCounterTotal(counter, count, "Converting To Luv...");
+
+ switch(src_color_space)
+ {
+ case IM_GRAY:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // scale to 0-1
+ float c0 = imColorReconstruct(*src_map0++, max);
+
+ // do gamma correction
+ c0 = imColorTransfer2Linear(c0);
+
+ // do conversion
+ c0 = imColorLuminance2Lightness(c0);
+
+ // then scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max); // update only the L component
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_RGB:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+
+ // scale to 0-1
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max);
+ float c2 = imColorReconstruct(*src_map2++, max);
+
+ // do gamma correction
+ c0 = imColorTransfer2Linear(c0);
+ c1 = imColorTransfer2Linear(c1);
+ c2 = imColorTransfer2Linear(c2);
+
+ imColorRGB2XYZ(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ imColorXYZ2Luv(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ // then scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1 + 0.5f, max);
+ *dst_map2++ = imColorQuantize(c2 + 0.5f, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_XYZ:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+ // scale to 0-1 and -0.5/+0.5
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max);
+ float c2 = imColorReconstruct(*src_map2++, max);
+
+ imColorXYZ2Luv(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ // scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1 + 0.5f, max);
+ *dst_map2++ = imColorQuantize(c2 + 0.5f, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ case IM_LAB:
+ max = (T)imColorMax(data_type);
+ for (i = 0; i < count; i++)
+ {
+ // to increase precision do intermediate conversions in float
+ // scale to 0-1 and -0.5/+0.5
+ float c0 = imColorReconstruct(*src_map0++, max);
+ float c1 = imColorReconstruct(*src_map1++, max) - 0.5f;
+ float c2 = imColorReconstruct(*src_map2++, max) - 0.5f;
+
+ imColorLab2XYZ(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+ imColorXYZ2Luv(c0, c1, c2, // convertion in-place
+ c0, c1, c2);
+
+ // scale back to 0-max
+ *dst_map0++ = imColorQuantize(c0, max);
+ *dst_map1++ = imColorQuantize(c1 + 0.5f, max);
+ *dst_map2++ = imColorQuantize(c2 + 0.5f, max);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class T>
+int iDoConvertColorSpace(int count, int data_type,
+ const T** src_data, int src_color_space,
+ T** dst_data, int dst_color_space)
+{
+ int ret = IM_ERR_DATA,
+ convert2rgb = 0;
+
+ if ((dst_color_space == IM_XYZ ||
+ dst_color_space == IM_LAB ||
+ dst_color_space == IM_LUV) &&
+ (src_color_space == IM_CMYK ||
+ src_color_space == IM_YCBCR))
+ {
+ convert2rgb = 1;
+ }
+
+ if (dst_color_space == IM_YCBCR && src_color_space != IM_RGB)
+ convert2rgb = 1;
+
+ int counter = imCounterBegin("Convert Color Space");
+
+ if (convert2rgb)
+ {
+ ret = iDoConvert2RGB(count, data_type, src_data, src_color_space, dst_data, counter);
+
+ if (ret != IM_ERR_NONE)
+ {
+ imCounterEnd(counter);
+ return ret;
+ }
+
+ src_data = (const T**)dst_data;
+ src_color_space = IM_RGB;
+ }
+
+ switch(dst_color_space)
+ {
+ case IM_GRAY:
+ ret = iDoConvert2Gray(count, data_type, src_data, src_color_space, dst_data, counter);
+ break;
+ case IM_RGB:
+ ret = iDoConvert2RGB(count, data_type, src_data, src_color_space, dst_data, counter);
+ break;
+ case IM_YCBCR:
+ ret = iDoConvert2YCbCr(count, data_type, src_data, src_color_space, dst_data, counter);
+ break;
+ case IM_XYZ:
+ ret = iDoConvert2XYZ(count, data_type, src_data, src_color_space, dst_data, counter);
+ break;
+ case IM_LAB:
+ ret = iDoConvert2Lab(count, data_type, src_data, src_color_space, dst_data, counter);
+ break;
+ case IM_LUV:
+ ret = iDoConvert2Luv(count, data_type, src_data, src_color_space, dst_data, counter);
+ break;
+ default:
+ ret = IM_ERR_DATA;
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static int iConvertColorSpace(const imImage* src_image, imImage* dst_image)
+{
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ return iDoConvertColorSpace(src_image->count, src_image->data_type,
+ (const imbyte**)src_image->data, src_image->color_space,
+ (imbyte**)dst_image->data, dst_image->color_space);
+ case IM_USHORT:
+ return iDoConvertColorSpace(src_image->count, src_image->data_type,
+ (const imushort**)src_image->data, src_image->color_space,
+ (imushort**)dst_image->data, dst_image->color_space);
+ case IM_INT:
+ return iDoConvertColorSpace(src_image->count, src_image->data_type,
+ (const int**)src_image->data, src_image->color_space,
+ (int**)dst_image->data, dst_image->color_space);
+ case IM_FLOAT:
+ return iDoConvertColorSpace(src_image->count, src_image->data_type,
+ (const float**)src_image->data, src_image->color_space,
+ (float**)dst_image->data, dst_image->color_space);
+ case IM_CFLOAT:
+ /* treat complex as two real values */
+ return iDoConvertColorSpace(2*src_image->count, src_image->data_type,
+ (const float**)src_image->data, src_image->color_space,
+ (float**)dst_image->data, dst_image->color_space);
+ }
+
+ return IM_ERR_DATA;
+}
+
+int imConvertColorSpace(const imImage* src_image, imImage* dst_image)
+{
+ int ret = IM_ERR_NONE;
+ assert(src_image);
+ assert(dst_image);
+
+ if (!imImageMatchDataType(src_image, dst_image))
+ return IM_ERR_DATA;
+
+ if (src_image->color_space != dst_image->color_space)
+ {
+ switch(dst_image->color_space)
+ {
+ case IM_RGB:
+ switch(src_image->color_space)
+ {
+ case IM_BINARY:
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->plane_size);
+ iConvertBinary((imbyte*)dst_image->data[0], dst_image->count, 255);
+ memcpy(dst_image->data[1], dst_image->data[0], dst_image->plane_size);
+ memcpy(dst_image->data[2], dst_image->data[0], dst_image->plane_size);
+ ret = IM_ERR_NONE;
+ break;
+ case IM_MAP:
+ iConvertMapToRGB((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], (imbyte*)dst_image->data[1], (imbyte*)dst_image->data[2], dst_image->count, src_image->palette, src_image->palette_count);
+ ret = IM_ERR_NONE;
+ break;
+ case IM_GRAY:
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->plane_size);
+ memcpy(dst_image->data[1], src_image->data[0], dst_image->plane_size);
+ memcpy(dst_image->data[2], src_image->data[0], dst_image->plane_size);
+ ret = IM_ERR_NONE;
+ break;
+ default:
+ ret = iConvertColorSpace(src_image, dst_image);
+ break;
+ }
+ break;
+ case IM_GRAY:
+ switch(src_image->color_space)
+ {
+ case IM_BINARY:
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->size);
+ iConvertBinary((imbyte*)dst_image->data[0], dst_image->count, 255);
+ ret = IM_ERR_NONE;
+ break;
+ case IM_MAP:
+ iConvertMap2Gray((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], dst_image->count, src_image->palette, src_image->palette_count);
+ ret = IM_ERR_NONE;
+ break;
+ case IM_YCBCR:
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->plane_size);
+ ret = IM_ERR_NONE;
+ break;
+ default:
+ ret = iConvertColorSpace(src_image, dst_image);
+ break;
+ }
+ break;
+ case IM_MAP:
+ switch(src_image->color_space)
+ {
+ case IM_BINARY: // no break, same procedure as gray
+ case IM_GRAY:
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->size);
+ dst_image->palette_count = src_image->palette_count;
+ memcpy(dst_image->palette, src_image->palette, dst_image->palette_count*sizeof(long));
+ ret = IM_ERR_NONE;
+ break;
+ case IM_RGB:
+ dst_image->palette_count = 256;
+ ret = imConvertRGB2Map(src_image->width, src_image->height,
+ (imbyte*)src_image->data[0], (imbyte*)src_image->data[1], (imbyte*)src_image->data[2],
+ (imbyte*)dst_image->data[0], dst_image->palette, &dst_image->palette_count);
+ break;
+ default:
+ ret = IM_ERR_DATA;
+ break;
+ }
+ break;
+ case IM_BINARY:
+ switch(src_image->color_space)
+ {
+ case IM_GRAY:
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->size);
+ iConvertBinary((imbyte*)dst_image->data[0], dst_image->count, 1);
+ ret = IM_ERR_NONE;
+ break;
+ case IM_MAP: // convert to gray, then convert to binary
+ iConvertMap2Gray((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], dst_image->count, src_image->palette, src_image->palette_count);
+ iConvertBinary((imbyte*)dst_image->data[0], dst_image->count, 1);
+ ret = IM_ERR_NONE;
+ break;
+ case IM_YCBCR: // convert to gray, then convert to binary
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->plane_size);
+ iConvertBinary((imbyte*)dst_image->data[0], dst_image->count, 1);
+ ret = IM_ERR_NONE;
+ break;
+ default: // convert to gray, then convert to binary
+ dst_image->color_space = IM_GRAY;
+ ret = iConvertColorSpace(src_image, dst_image);
+ dst_image->color_space = IM_BINARY;
+ if (ret == IM_ERR_NONE)
+ iConvertBinary((imbyte*)dst_image->data[0], dst_image->count, 1);
+ ret = IM_ERR_NONE;
+ break;
+ }
+ break;
+ case IM_YCBCR:
+ switch(src_image->color_space)
+ {
+ case IM_GRAY:
+ memcpy(dst_image->data[0], src_image->data[0], dst_image->plane_size);
+ ret = IM_ERR_NONE;
+ break;
+ default:
+ ret = iConvertColorSpace(src_image, dst_image);
+ break;
+ }
+ break;
+ default:
+ ret = iConvertColorSpace(src_image, dst_image);
+ break;
+ }
+ }
+
+ if (src_image->has_alpha && dst_image->has_alpha)
+ memcpy(dst_image->data[dst_image->depth], src_image->data[src_image->depth], src_image->plane_size);
+ else if (dst_image->color_space == IM_RGB && dst_image->data_type == IM_BYTE && dst_image->has_alpha)
+ {
+ if (src_image->color_space == IM_RGB)
+ {
+ imbyte* transp_color = (imbyte*)imImageGetAttribute(src_image, "TransparencyColor", NULL, NULL);
+ if (transp_color)
+ iConvertSetTranspColor((imbyte**)dst_image->data, dst_image->count, *(transp_color+0), *(transp_color+1), *(transp_color+2));
+ else
+ memset(dst_image->data[3], 255, dst_image->count);
+ }
+ else
+ {
+ int transp_count;
+ imbyte* transp_index = (imbyte*)imImageGetAttribute(src_image, "TransparencyIndex", NULL, NULL);
+ imbyte* transp_map = (imbyte*)imImageGetAttribute(src_image, "TransparencyMap", NULL, &transp_count);
+ if (transp_map)
+ iConvertSetTranspMap((imbyte*)src_image->data[0], (imbyte*)dst_image->data[3], dst_image->count, transp_map, transp_count);
+ else if (transp_index)
+ iConvertSetTranspIndex((imbyte*)src_image->data[0], (imbyte*)dst_image->data[3], dst_image->count, *transp_index);
+ else
+ memset(dst_image->data[3], 255, dst_image->count);
+ }
+ }
+
+ return ret;
+}
+
diff --git a/im/src/im_converttype.cpp b/im/src/im_converttype.cpp
new file mode 100755
index 0000000..ee69b6f
--- /dev/null
+++ b/im/src/im_converttype.cpp
@@ -0,0 +1,555 @@
+/** \file
+ * \brief Image Data Type Conversion
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_converttype.cpp,v 1.3 2009/09/29 21:30:57 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_util.h"
+#include "im_complex.h"
+#include "im_image.h"
+#include "im_convert.h"
+#include "im_color.h"
+#include "im_counter.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <memory.h>
+
+
+/* IMPORTANT: leave template functions not "static"
+ because of some weird compiler bizarre errors.
+ Report on AIX C++.
+*/
+
+/* if gamma is applied then factor contains two conversions
+ one for applying gamma,
+ and other for normal destiny conversion to dst_min-dst_max range.
+ because gamma(0) = 0
+ For EXP: gamma(x) = (e^(g*x))-1
+ For LOG: gamma(x) = log((g*x)+1)
+ because gamma(1) = 1
+ gfactor = exp(g)-1
+ gfactor = log(g+1)
+*/
+
+inline float iGammaFactor(float range, float gamma)
+{
+ if (gamma == 0)
+ return range;
+ else if (gamma < 0)
+ return range/float(log((-gamma) + 1));
+ else
+ return range/float(exp(gamma) - 1);
+}
+
+inline float iGammaFunc(float factor, float min, float gamma, float value)
+{
+ // Here 0<value<1 (always)
+ if (gamma != 0)
+ {
+ if (gamma < 0)
+ value = log(value*(-gamma) + 1);
+ else
+ value = exp(value*gamma) - 1;
+ }
+
+ return factor*value + min;
+}
+
+inline int iIntMin()
+{
+ return (int)(-8388608.0f);
+}
+inline int iIntMax()
+{
+ return (int)(+8388607.0f);
+}
+
+/// Generic Abssolute
+template <class T>
+inline T iAbs(const T& v)
+{
+ if (v < 0)
+ return -1*v;
+ return v;
+}
+
+template <class T>
+inline void iDataTypeIntMax(T& max)
+{
+ int size_of = sizeof(T);
+ int data_type = (size_of == 1)? IM_BYTE: (size_of == 2)? IM_USHORT: IM_INT;
+ max = (T)imColorMax(data_type);
+}
+
+template <class T>
+inline void iMinMaxAbs(int count, const T *map, T& min, T& max, int abssolute)
+{
+ if (abssolute)
+ min = iAbs(*map++);
+ else
+ min = *map++;
+
+ max = min;
+
+ for (int i = 1; i < count; i++)
+ {
+ T value;
+
+ if (abssolute)
+ value = iAbs(*map++);
+ else
+ value = *map++;
+
+ if (value > max)
+ max = value;
+ else if (value < min)
+ min = value;
+ }
+
+ if (min == max)
+ {
+ max = min + 1;
+
+ if (min != 0)
+ min = min - 1;
+ }
+}
+
+template <class SRCT, class DSTT>
+int iCopy(int count, const SRCT *src_map, DSTT *dst_map)
+{
+ for (int i = 0; i < count; i++)
+ {
+ *dst_map++ = (DSTT)(*src_map++);
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class SRCT, class DSTT>
+int iCopyCrop(int count, const SRCT *src_map, DSTT *dst_map, int abssolute)
+{
+ SRCT value;
+ DSTT dst_max;
+ iDataTypeIntMax(dst_max);
+
+ for (int i = 0; i < count; i++)
+ {
+ if (abssolute)
+ value = iAbs(*src_map++);
+ else
+ value = *src_map++;
+
+ if (value > dst_max)
+ value = (SRCT)dst_max;
+
+ if (!(value >= 0))
+ value = 0;
+
+ *dst_map++ = (DSTT)(value);
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class SRCT>
+int iPromote2Cpx(int count, const SRCT *src_map, imcfloat *dst_map)
+{
+ for (int i = 0; i < count; i++)
+ {
+ dst_map->real = (float)(*src_map++);
+ dst_map++;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class SRCT, class DSTT>
+int iConvertInt2Int(int count, const SRCT *src_map, DSTT *dst_map, int abssolute, int cast_mode, int counter)
+{
+ SRCT min, max;
+
+ if (cast_mode == IM_CAST_MINMAX)
+ {
+ iMinMaxAbs(count, src_map, min, max, abssolute);
+
+ if (min >= 0 && max <= 255)
+ {
+ min = 0;
+ max = 255;
+ }
+ }
+ else
+ {
+ min = 0;
+ iDataTypeIntMax(max);
+ }
+
+ DSTT dst_max;
+ iDataTypeIntMax(dst_max);
+
+ float factor = ((float)dst_max + 1.0f) / ((float)max - (float)min + 1.0f);
+
+ for (int i = 0; i < count; i++)
+ {
+ SRCT value;
+ if (abssolute)
+ value = iAbs(*src_map++);
+ else
+ value = *src_map++;
+
+ if (value >= max)
+ *dst_map++ = dst_max;
+ else if (value <= min)
+ *dst_map++ = 0;
+ else
+ *dst_map++ = (DSTT)imResample(value - min, factor);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class SRCT>
+int iPromoteInt2Real(int count, const SRCT *src_map, float *dst_map, float gamma, int abssolute, int cast_mode, int counter)
+{
+ SRCT min, max;
+
+ if (cast_mode == IM_CAST_MINMAX)
+ {
+ iMinMaxAbs(count, src_map, min, max, abssolute);
+
+ if (min >= 0 && max <= 255)
+ {
+ min = 0;
+ max = 255;
+ }
+ }
+ else
+ {
+ min = 0;
+ iDataTypeIntMax(max);
+
+ if (max == 16777215 && !abssolute) /* IM_INT */
+ {
+ min = (SRCT)iIntMin();
+ max = (SRCT)iIntMax();
+ }
+ }
+
+ float range = float(max - min + 1);
+ float dst_min = 0.0f;
+ float dst_max = 1.0f;
+ int size_of = sizeof(SRCT);
+ if (size_of == 4 && !abssolute)
+ {
+ dst_min = -0.5f;
+ dst_max = +0.5f;
+ }
+
+ gamma = -gamma; // gamma is inverted here, because we are promoting int2real
+ float factor = iGammaFactor(1.0f, gamma);
+
+ for (int i = 0; i < count; i++)
+ {
+ float fvalue;
+ if (abssolute)
+ fvalue = (iAbs(*src_map++) - min + 0.5f)/range;
+ else
+ fvalue = (*src_map++ - min + 0.5f)/range;
+
+ // Now 0 <= value <= 1 (if min-max are correct)
+
+ if (fvalue >= 1)
+ *dst_map++ = dst_max;
+ else if (fvalue <= 0)
+ *dst_map++ = dst_min;
+ else
+ *dst_map++ = iGammaFunc(factor, dst_min, gamma, fvalue);
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class DSTT>
+int iDemoteReal2Int(int count, const float *src_map, DSTT *dst_map, float gamma, int abssolute, int cast_mode, int counter)
+{
+ float min, max;
+
+ DSTT dst_min = 0, dst_max;
+ iDataTypeIntMax(dst_max);
+ if (dst_max == 16777215 && !abssolute) /* IM_INT */
+ {
+ dst_min = (DSTT)iIntMin();
+ dst_max = (DSTT)iIntMax();
+ }
+
+ if (cast_mode == IM_CAST_MINMAX)
+ iMinMaxAbs(count, src_map, min, max, abssolute);
+ else
+ {
+ min = 0;
+ max = 1;
+ }
+
+ int dst_range = dst_max - dst_min + 1;
+ float range = max - min;
+
+ float factor = iGammaFactor((float)dst_range, gamma);
+
+ for (int i = 0; i < count; i++)
+ {
+ float value;
+ if (abssolute)
+ value = ((float)iAbs(*src_map++) - min)/range;
+ else
+ value = (*src_map++ - min)/range;
+
+ if (i==3603)
+ i=i;
+
+ // Now 0 <= value <= 1 (if min-max are correct)
+
+ if (value >= 1)
+ *dst_map++ = dst_max;
+ else if (value <= 0)
+ *dst_map++ = dst_min;
+ else
+ {
+ value = iGammaFunc(factor, (float)dst_min, gamma, value);
+ int ivalue = imRound(value);
+ if (ivalue >= dst_max)
+ *dst_map++ = dst_max;
+ else if (ivalue <= dst_min)
+ *dst_map++ = dst_min;
+ else
+ *dst_map++ = (DSTT)imRound(value - 0.5f);
+ }
+
+ if (!imCounterInc(counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int iDemoteCpx2Real(int count, const imcfloat* src_map, float *dst_map, int cpx2real)
+{
+ float (*CpxCnv)(const imcfloat& cpx) = NULL;
+
+ switch(cpx2real)
+ {
+ case IM_CPX_REAL: CpxCnv = cpxreal; break;
+ case IM_CPX_IMAG: CpxCnv = cpximag; break;
+ case IM_CPX_MAG: CpxCnv = cpxmag; break;
+ case IM_CPX_PHASE: CpxCnv = cpxphase; break;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ *dst_map++ = CpxCnv(*src_map++);
+ }
+
+ return IM_ERR_NONE;
+}
+
+template <class DSTT>
+int iDemoteCpx2Int(int count, const imcfloat* src_map, DSTT *dst_map, int cpx2real, float gamma, int abssolute, int cast_mode, int counter)
+{
+ float* real_map = (float*)malloc(count*sizeof(float));
+ if (!real_map) return IM_ERR_MEM;
+
+ iDemoteCpx2Real(count, src_map, real_map, cpx2real);
+
+ if (iDemoteReal2Int(count, real_map, dst_map, gamma, abssolute, cast_mode, counter) != IM_ERR_NONE)
+ {
+ free(real_map);
+ return IM_ERR_COUNTER;
+ }
+
+ free(real_map);
+ return IM_ERR_NONE;
+}
+
+template <class SRCT>
+int iPromoteInt2Cpx(int count, const SRCT* src_map, imcfloat *dst_map, float gamma, int abssolute, int cast_mode, int counter)
+{
+ float* real_map = (float*)malloc(count*sizeof(float));
+ if (!real_map) return IM_ERR_MEM;
+
+ if (iPromoteInt2Real(count, src_map, real_map, gamma, abssolute, cast_mode, counter) != IM_ERR_NONE)
+ {
+ free(real_map);
+ return IM_ERR_COUNTER;
+ }
+
+ iPromote2Cpx(count, real_map, dst_map);
+
+ free(real_map);
+ return IM_ERR_NONE;
+}
+
+int imConvertDataType(const imImage* src_image, imImage* dst_image, int cpx2real, float gamma, int abssolute, int cast_mode)
+{
+ assert(src_image);
+ assert(dst_image);
+
+ if (!imImageMatchColorSpace(src_image, dst_image))
+ return IM_ERR_DATA;
+
+ if (src_image->data_type == dst_image->data_type)
+ return IM_ERR_DATA;
+
+ int total_count = src_image->depth * src_image->count;
+ int ret = IM_ERR_DATA;
+ int counter = imCounterBegin("Convert Data Type");
+ char msg[50];
+ sprintf(msg, "Converting to %s...", imDataTypeName(dst_image->data_type));
+ imCounterTotal(counter, total_count, msg);
+
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ switch(dst_image->data_type)
+ {
+ case IM_USHORT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopy(total_count, (const imbyte*)src_image->data[0], (imushort*)dst_image->data[0]);
+ else
+ ret = iConvertInt2Int(total_count, (const imbyte*)src_image->data[0], (imushort*)dst_image->data[0], abssolute, cast_mode, counter);
+ break;
+ case IM_INT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopy(total_count, (const imbyte*)src_image->data[0], (int*)dst_image->data[0]);
+ else
+ ret = iConvertInt2Int(total_count, (const imbyte*)src_image->data[0], (int*)dst_image->data[0], abssolute, cast_mode, counter);
+ break;
+ case IM_FLOAT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopy(total_count, (const imbyte*)src_image->data[0], (float*)dst_image->data[0]);
+ else
+ ret = iPromoteInt2Real(total_count, (const imbyte*)src_image->data[0], (float*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_CFLOAT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iPromote2Cpx(total_count, (const imbyte*)src_image->data[0], (imcfloat*)dst_image->data[0]);
+ else
+ ret = iPromoteInt2Cpx(total_count, (const imbyte*)src_image->data[0], (imcfloat*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ }
+ break;
+ case IM_USHORT:
+ switch(dst_image->data_type)
+ {
+ case IM_BYTE:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopyCrop(total_count, (const imushort*)src_image->data[0], (imbyte*)dst_image->data[0], abssolute);
+ else
+ ret = iConvertInt2Int(total_count, (const imushort*)src_image->data[0], (imbyte*)dst_image->data[0], abssolute, cast_mode, counter);
+ break;
+ case IM_INT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopy(total_count, (const imushort*)src_image->data[0], (int*)dst_image->data[0]);
+ else
+ ret = iConvertInt2Int(total_count, (const imushort*)src_image->data[0], (int*)dst_image->data[0], abssolute, cast_mode, counter);
+ break;
+ case IM_FLOAT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopy(total_count, (const imushort*)src_image->data[0], (float*)dst_image->data[0]);
+ else
+ ret = iPromoteInt2Real(total_count, (const imushort*)src_image->data[0], (float*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_CFLOAT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iPromote2Cpx(total_count, (const imushort*)src_image->data[0], (imcfloat*)dst_image->data[0]);
+ else
+ ret = iPromoteInt2Cpx(total_count, (const imushort*)src_image->data[0], (imcfloat*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ }
+ break;
+ case IM_INT:
+ switch(dst_image->data_type)
+ {
+ case IM_BYTE:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopyCrop(total_count, (const int*)src_image->data[0], (imbyte*)dst_image->data[0], abssolute);
+ else
+ ret = iConvertInt2Int(total_count, (const int*)src_image->data[0], (imbyte*)dst_image->data[0], abssolute, cast_mode, counter);
+ break;
+ case IM_USHORT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopyCrop(total_count, (const int*)src_image->data[0], (imushort*)dst_image->data[0], abssolute);
+ else
+ ret = iConvertInt2Int(total_count, (const int*)src_image->data[0], (imushort*)dst_image->data[0], abssolute, cast_mode, counter);
+ break;
+ case IM_FLOAT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopy(total_count, (const int*)src_image->data[0], (float*)dst_image->data[0]);
+ else
+ ret = iPromoteInt2Real(total_count, (const int*)src_image->data[0], (float*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_CFLOAT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iPromote2Cpx(total_count, (const int*)src_image->data[0], (imcfloat*)dst_image->data[0]);
+ else
+ ret = iPromoteInt2Cpx(total_count, (const int*)src_image->data[0], (imcfloat*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ }
+ break;
+ case IM_FLOAT:
+ switch(dst_image->data_type)
+ {
+ case IM_BYTE:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopyCrop(total_count, (const float*)src_image->data[0], (imbyte*)dst_image->data[0], abssolute);
+ else
+ ret = iDemoteReal2Int(total_count, (const float*)src_image->data[0], (imbyte*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_USHORT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopyCrop(total_count, (const float*)src_image->data[0], (imushort*)dst_image->data[0], abssolute);
+ else
+ ret = iDemoteReal2Int(total_count, (const float*)src_image->data[0], (imushort*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_INT:
+ if (cast_mode == IM_CAST_DIRECT)
+ ret = iCopy(total_count, (const float*)src_image->data[0], (int*)dst_image->data[0]);
+ else
+ ret = iDemoteReal2Int(total_count, (const float*)src_image->data[0], (int*)dst_image->data[0], gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_CFLOAT:
+ ret = iPromote2Cpx(total_count, (const float*)src_image->data[0], (imcfloat*)dst_image->data[0]);
+ break;
+ }
+ break;
+ case IM_CFLOAT:
+ switch(dst_image->data_type)
+ {
+ case IM_BYTE:
+ ret = iDemoteCpx2Int(total_count, (const imcfloat*)src_image->data[0], (imbyte*)dst_image->data[0], cpx2real, gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_USHORT:
+ ret = iDemoteCpx2Int(total_count, (const imcfloat*)src_image->data[0], (imushort*)dst_image->data[0], cpx2real, gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_INT:
+ ret = iDemoteCpx2Int(total_count, (const imcfloat*)src_image->data[0], (int*)dst_image->data[0], cpx2real, gamma, abssolute, cast_mode, counter);
+ break;
+ case IM_FLOAT:
+ ret = iDemoteCpx2Real(total_count, (const imcfloat*)src_image->data[0], (float*)dst_image->data[0], cpx2real);
+ break;
+ }
+ break;
+ }
+
+ imCounterEnd(counter);
+ return ret;
+}
diff --git a/im/src/im_counter.cpp b/im/src/im_counter.cpp
new file mode 100755
index 0000000..8c5cd5c
--- /dev/null
+++ b/im/src/im_counter.cpp
@@ -0,0 +1,151 @@
+/** \file
+ * \brief Processing Counter
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_counter.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include "im_counter.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+
+static imCounterCallback iCounterFunc = NULL;
+static void* iCounterUserData = NULL;
+
+imCounterCallback imCounterSetCallback(void* user_data, imCounterCallback counter_func)
+{
+ imCounterCallback old_counter_func = iCounterFunc;
+ iCounterFunc = counter_func;
+ if (user_data)
+ iCounterUserData = user_data;
+ return old_counter_func;
+}
+
+struct iCounter
+{
+ int total;
+ int current;
+ int sequence;
+ const char* message;
+};
+
+#define MAX_COUNTERS 10
+static iCounter iCounterList[MAX_COUNTERS];
+
+int imCounterBegin(const char* title)
+{
+ static int first = 1;
+ if (first)
+ {
+ memset(iCounterList, 0, MAX_COUNTERS*sizeof(iCounter));
+ first = 0;
+ }
+
+ if (!iCounterFunc) // counter management is useless
+ return -1;
+
+ int counter = -1;
+ for (int i = 0; i < MAX_COUNTERS; i++)
+ {
+ if (iCounterList[i].sequence == 0 || // the counter is free
+ iCounterList[i].current == 0) // or we are in a sequence
+ {
+ counter = i;
+ break;
+ }
+ }
+
+ if (counter == -1) return -1; // too many counters
+
+ iCounter *ct = &iCounterList[counter];
+
+ ct->sequence++;
+
+ if (ct->sequence == 1) // top level counter
+ iCounterFunc(counter, iCounterUserData, title, -1);
+
+ return counter;
+}
+
+void imCounterEnd(int counter)
+{
+ if (counter == -1 || !iCounterFunc) return; // invalid counter
+
+ iCounter *ct = &iCounterList[counter];
+
+ if (ct->sequence == 1) // top level counter
+ {
+ iCounterFunc(counter, iCounterUserData, NULL, 1001);
+ memset(ct, 0, sizeof(iCounter));
+ }
+ else
+ ct->sequence--;
+}
+
+int imCounterInc(int counter)
+{
+ if (counter == -1 || !iCounterFunc) // invalid counter
+ return 1;
+
+ iCounter *ct = &iCounterList[counter];
+
+ if (ct->sequence == 0 || // counter with no begin or no total
+ ct->total == 0)
+ return 1;
+
+ const char* msg = NULL;
+ if (ct->current == 0)
+ msg = ct->message;
+
+ ct->current++;
+
+ int progress = (int)((ct->current * 1000.0f)/ct->total);
+
+ if (ct->current == ct->total)
+ ct->current = 0;
+
+ return iCounterFunc(counter, iCounterUserData, msg, progress);
+}
+
+int imCounterIncTo(int counter, int count)
+{
+ if (counter == -1 || !iCounterFunc) // invalid counter
+ return 1;
+
+ iCounter *ct = &iCounterList[counter];
+
+ if (ct->sequence == 0 || // counter with no begin or no total
+ ct->total == 0)
+ return 1;
+
+ if (count <= 0) count = 0;
+ if (count >= ct->total) count = ct->total;
+
+ ct->current = count;
+
+ const char* msg = NULL;
+ if (ct->current == 0)
+ msg = ct->message;
+
+ int progress = (int)((ct->current * 1000.0f)/ct->total);
+
+ if (ct->current == ct->total)
+ ct->current = 0;
+
+ return iCounterFunc(counter, iCounterUserData, msg, progress);
+}
+
+void imCounterTotal(int counter, int total, const char* message)
+{
+ if (counter == -1 || !iCounterFunc) return; // invalid counter
+
+ iCounter *ct = &iCounterList[counter];
+
+ if (ct->sequence == 0) return; // counter with no begin
+
+ ct->message = message;
+ ct->total = total;
+ ct->current = 0;
+}
diff --git a/im/src/im_datatype.cpp b/im/src/im_datatype.cpp
new file mode 100755
index 0000000..c75483e
--- /dev/null
+++ b/im/src/im_datatype.cpp
@@ -0,0 +1,54 @@
+/** \file
+ * \brief Data Type Utilities
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_datatype.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include "im.h"
+#include "im_util.h"
+
+#include <assert.h>
+
+typedef struct _iTypeInfo
+{
+ int size;
+ unsigned long max;
+ long min;
+ char* name;
+} iTypeInfo;
+
+static iTypeInfo iTypeInfoTable[] =
+{
+ {1, 255, 0, "byte"},
+ {2, 65535, 0, "ushort"},
+ {4, 2147483647, -2147483647-1, "int"},
+ {4, 0, 0, "float"},
+ {8, 0, 0, "cfloat"}
+};
+
+const char* imDataTypeName(int data_type)
+{
+ assert(data_type >= IM_BYTE && data_type <= IM_CFLOAT);
+ return iTypeInfoTable[data_type].name;
+}
+
+int imDataTypeSize(int data_type)
+{
+ assert(data_type >= IM_BYTE && data_type <= IM_CFLOAT);
+ assert(sizeof(int) == 4);
+ return iTypeInfoTable[data_type].size;
+}
+
+unsigned long imDataTypeIntMax(int data_type)
+{
+ assert(data_type >= IM_BYTE && data_type <= IM_CFLOAT);
+ return iTypeInfoTable[data_type].max;
+}
+
+long imDataTypeIntMin(int data_type)
+{
+ assert(data_type >= IM_BYTE && data_type <= IM_CFLOAT);
+ return iTypeInfoTable[data_type].min;
+}
diff --git a/im/src/im_dib.cpp b/im/src/im_dib.cpp
new file mode 100755
index 0000000..3dd6780
--- /dev/null
+++ b/im/src/im_dib.cpp
@@ -0,0 +1,1136 @@
+/** \file
+ * \brief Windows DIB
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_dib.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include <windows.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "im_dib.h"
+
+/*****************
+ Private Funtions
+*****************/
+
+/* Long returned in getpixel is an array of 4 bytes, not actually a DWORD */
+/* 32 bpp max */
+/* Windows use Little Endian always, this means LSB first: 0xF3F2F1F0 = "F0F1F2F3" */
+
+#define iSETDWORD(_vLong, _Line, _Nb) \
+ { \
+ unsigned char* _pLong = (unsigned char*)&_vLong; \
+ int b = _Nb; \
+ while(b--) \
+ *_pLong++ = *_Line++; \
+ }
+
+#define iGETDWORD(_vLong, _Line, _Nb) \
+ { \
+ unsigned char* _pLong = (unsigned char*)&_vLong; \
+ int b = _Nb; \
+ while(b--) \
+ *_Line++ = *_pLong++; \
+ }
+
+#define iGETDWORDMASK(_vLong, _vMask, _Line, _Nb) \
+ { \
+ unsigned char* _pLong = (unsigned char*)&_vLong; \
+ unsigned char* _pMask = (unsigned char*)&_vMask; \
+ int b = _Nb; \
+ while(b--) \
+ *_Line++ = *_pLong++ | (~*_pMask++ & *_Line); \
+ }
+
+static unsigned int iMakeBitMask(int bpp)
+{
+ unsigned int mask = 1;
+
+ while (bpp > 1)
+ {
+ mask = (mask << 1) + 1;
+ bpp--;
+ }
+
+ return mask;
+}
+
+static unsigned int iLineGetPixel1(unsigned char* line, int col)
+{
+ return (line[col / 8] >> (7 - col % 8)) & 0x01; /* LSB is filled */
+}
+
+static void iLineSetPixel1(unsigned char* line, int col, unsigned int pixel)
+{
+ if (pixel) /* only test 1/0 */
+ line[col / 8] |= (0x01 << (7 - (col % 8)));
+ else
+ line[col / 8] &= (0xFE << (7 - (col % 8)));
+}
+
+static unsigned int iLineGetPixel4(unsigned char* line, int col)
+{
+ return (line[col / 2] >> ((1 - col % 2) * 4)) & 0x0F; /* LSB is filled */
+}
+
+static void iLineSetPixel4(unsigned char* line, int col, unsigned int pixel)
+{
+ unsigned char mask = (col % 2)? 0xF0: 0x0F; /* LSB is used */
+ line[col/2] = (unsigned char)((mask & (((unsigned char)pixel) << ((1 - col % 2) * 4))) | (~mask & line[col/2]));
+}
+
+static unsigned int iLineGetPixel8(unsigned char* line, int col)
+{
+ return line[col]; /* LSB is filled */
+}
+
+static void iLineSetPixel8(unsigned char* line, int col, unsigned int pixel)
+{
+ line[col] = (unsigned char)pixel; /* LSB is used */
+}
+
+static unsigned int iLineGetPixel16(unsigned char* line, int col)
+{
+ return ((unsigned short*)line)[col]; /* 0xF1F0 => "F0F10000" */
+}
+
+static void iLineSetPixel16(unsigned char* line, int col, unsigned int pixel)
+{
+ ((unsigned short*)line)[col] = (unsigned short)pixel; /* inverse of above */
+}
+
+static unsigned int iLineGetPixel24(unsigned char* line, int col)
+{
+ unsigned int pixel = 0;
+ line += col*3;
+ iSETDWORD(pixel, line, 3);
+ return pixel;
+}
+
+static void iLineSetPixel24(unsigned char* line, int col, unsigned int pixel)
+{
+ line += col*3;
+ iGETDWORD(pixel, line, 3);
+}
+
+static unsigned int iLineGetPixel32(unsigned char* line, int col)
+{
+ return ((unsigned int*)line)[col]; /* direct mapping */
+}
+
+static void iLineSetPixel32(unsigned char* line, int col, unsigned int pixel)
+{
+ ((unsigned int*)line)[col] = pixel; /* direct mapping */
+}
+
+static int iGetPixelAnyBpp = 0;
+static unsigned int iGetPixelAnyMask = 0;
+
+static unsigned int iAnyGet(unsigned char* line, int col, int bpp)
+{
+ int s_byte = (col*bpp) >> 3;
+ int s_bit = (col*bpp) & 0x7;
+ unsigned int pixel = 0;
+ unsigned int mask = (~0) >> (32-bpp);
+ int n_bytes = (bpp + s_bit + 7) >> 3;
+ int shift = (n_bytes << 3) - bpp - s_bit;
+ line += s_byte;
+ while (n_bytes)
+ {
+ pixel |= *line++;
+ if (--n_bytes > 0) pixel <<= 8;
+ else break;
+ }
+ pixel >>= shift;
+ return pixel & mask;
+}
+
+static void iAnySet(unsigned char* line, int col, int bpp, unsigned int pixel)
+{
+ int s_byte = (col*bpp) >> 3;
+ int s_bit = (col*bpp) & 0x7;
+ unsigned int mask = (~0) >> (32-bpp);
+ int n_bytes = (bpp + s_bit + 7) >> 3;
+ int shift = (n_bytes << 3) - bpp - s_bit;
+ unsigned char* p_pixel = (unsigned char*) &pixel, *p_mask = (unsigned char*) &mask;
+ line += s_byte + n_bytes - 1;
+ pixel <<= shift;
+ mask <<= shift;
+ while (n_bytes--) {
+ *line = (*line & ~(*p_mask)) | (*p_pixel & *p_mask);
+ p_mask++; p_pixel++; line--;
+ }
+}
+
+static unsigned int iLineGetPixelAny(unsigned char* line, int col)
+{
+ return iAnyGet(line, col, iGetPixelAnyBpp);
+#if 0
+ unsigned int pixel = 0;
+ int rbits = (col * iGetPixelAnyBpp) % 8; /* calc remaining bits */
+ line += (col * iGetPixelAnyBpp) / 8; /* position pointer */
+
+ /* transfer from pixel line to a DWORD in little endian, so it can be shifted */
+ {
+ int nbytes = (iGetPixelAnyBpp + rbits + 7) / 8; /* bytes used */
+ iSETDWORD(pixel, line, nbytes);
+ }
+
+ /* shift down pixel remaining bits and mask extra non pixel bits */
+ return (pixel >> rbits) & iGetPixelAnyMask;
+#endif
+}
+
+static int iSetPixelAnyBpp = 0;
+static unsigned int iSetPixelAnyMask = 0;
+
+static void iLineSetPixelAny(unsigned char* line, int col, unsigned int pixel)
+{
+ iAnySet(line, col, iSetPixelAnyBpp, pixel);
+#if 0
+ int rbits = (col * iSetPixelAnyBpp) % 8; /* calc remaining bits */
+ line += (col * iSetPixelAnyBpp) / 8; /* position pointer */
+
+ pixel = pixel << rbits; /* position bits */
+
+ {
+ unsigned int mask = iSetPixelAnyMask << rbits; /* position mask */
+ int nbytes = (iGetPixelAnyBpp + rbits + 7) / 8; /* bytes used */
+ iGETDWORDMASK(pixel, mask, line, nbytes);
+ }
+#endif
+}
+
+static long iQuad2Long(RGBQUAD* quad_color)
+{
+ return (((unsigned long)quad_color->rgbRed) << 16) |
+ (((unsigned long)quad_color->rgbGreen) << 8) |
+ (((unsigned long)quad_color->rgbBlue) << 0);
+}
+
+static RGBQUAD iLong2Quad(long long_color)
+{
+ RGBQUAD quad_color;
+
+ quad_color.rgbRed = (unsigned char)(((long_color) >> 16) & 0xFF);
+ quad_color.rgbGreen = (unsigned char)(((long_color) >> 8) & 0xFF);
+ quad_color.rgbBlue = (unsigned char)(((long_color) >> 0) & 0xFF);
+
+ return quad_color;
+}
+
+static int iImageLineSize(int width, int bpp)
+{
+ return (width * bpp + 7) / 8; /* 1 byte boundary */
+}
+
+static int iLineSize(int width, int bpp)
+{
+ return ((width * bpp + 31) / 32) * 4; /* 4 bytes boundary */
+}
+
+static void iInitHeadersReference(imDib* dib)
+{
+ dib->bmi = (BITMAPINFO*)dib->dib;
+ dib->bmih = (BITMAPINFOHEADER*)dib->dib;
+ dib->bmic = (RGBQUAD*)(dib->dib + sizeof(BITMAPINFOHEADER));
+}
+
+static void iInitSizes(imDib* dib, int width, int height, int bpp)
+{
+ dib->line_size = iLineSize(width, bpp);
+ dib->pad_size = dib->line_size - iImageLineSize(width, bpp);
+ dib->bits_size = dib->line_size * height;
+ dib->size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * dib->palette_count + dib->bits_size;
+}
+
+static void iInitInfoHeader(BITMAPINFOHEADER* bmih, int width, int height, int bpp, int palette_count)
+{
+ bmih->biSize = sizeof(BITMAPINFOHEADER);
+ bmih->biWidth = width;
+ bmih->biHeight = height;
+ bmih->biPlanes = 1;
+ bmih->biBitCount = (WORD)bpp;
+ bmih->biCompression = 0;
+ bmih->biSizeImage = 0;
+ bmih->biClrUsed = palette_count;
+ bmih->biClrImportant = 0;
+
+ {
+ HDC ScreenDC = GetDC(NULL);
+
+ bmih->biXPelsPerMeter = (unsigned int)(GetDeviceCaps(ScreenDC, LOGPIXELSX) / 0.0254);
+ bmih->biYPelsPerMeter = (unsigned int)(GetDeviceCaps(ScreenDC, LOGPIXELSY) / 0.0254);
+
+ ReleaseDC(NULL, ScreenDC);
+ }
+}
+
+static void iInitBits(imDib* dib, BYTE* bits)
+{
+ if (bits == NULL)
+ dib->bits = dib->dib + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * dib->palette_count;
+ else
+ dib->bits = bits;
+}
+
+static int iGetValidBpp(int bpp)
+{
+ if (bpp == 1)
+ bpp = 1;
+ else if (bpp <= 4)
+ bpp = 4;
+ else if (bpp <= 8)
+ bpp = 8;
+ else if (bpp <= 16)
+ bpp = 16;
+ else if (bpp <= 24)
+ bpp = 24;
+ else if (bpp <= 32)
+ bpp = 32;
+ else
+ bpp = 0;
+
+ return bpp;
+}
+
+static int iCheckHeader(BITMAPINFOHEADER *bmih)
+{
+ if (bmih->biSize != sizeof(BITMAPINFOHEADER))
+ return 0;
+
+ if (bmih->biWidth <= 0)
+ return 0;
+
+ if (bmih->biHeight == 0)
+ return 0;
+
+ {
+ int bpp = iGetValidBpp(bmih->biBitCount);
+ if (!bpp)
+ return 0;
+
+ if (bmih->biCompression == BI_RLE8 && bpp != 8)
+ return 0;
+
+ if (bmih->biCompression == BI_RLE4 && bpp != 4)
+ return 0;
+
+ if (bmih->biCompression == BI_BITFIELDS && (bpp != 16 || bpp != 32))
+ return 0;
+
+ if (bmih->biHeight < 0 && (bmih->biCompression == BI_RLE8 || bmih->biCompression == BI_RLE4))
+ return 0;
+
+/* if (bmih->biCompression == BI_JPEG || bmih->biCompression == BI_PNG)
+ return 0; */
+ }
+
+ return 1;
+}
+
+/*****************
+ Creation
+*****************/
+
+static void AllocDib(imDib* dib)
+{
+ dib->dib = NULL;
+ dib->handle = GlobalAlloc(GMEM_MOVEABLE, dib->size);
+ if (!dib->handle) return;
+ dib->dib = (BYTE*)GlobalLock(dib->handle);
+}
+
+imDib* imDibCreate(int width, int height, int bpp)
+{
+ imDib* dib;
+ int obpp = bpp;
+
+ bpp = iGetValidBpp(abs(bpp));
+
+ assert(width > 0 && height > 0);
+ assert(bpp);
+
+ dib = (imDib*)malloc(sizeof(imDib));
+
+ if (bpp > 8)
+ {
+ if ((bpp == 16 || bpp == 32) && obpp < 0)
+ dib->palette_count = 3;
+ else
+ dib->palette_count = 0;
+ }
+ else
+ dib->palette_count = 1 << bpp;
+
+ iInitSizes(dib, width, height, bpp);
+
+ AllocDib(dib);
+ if (dib->dib == NULL)
+ {
+ free(dib);
+ return NULL;
+ }
+
+ iInitHeadersReference(dib);
+
+ iInitInfoHeader(dib->bmih, width, height, bpp, dib->palette_count);
+
+ iInitBits(dib, NULL);
+
+ dib->is_reference = 0;
+
+ return dib;
+}
+
+imDib* imDibCreateSection(HDC hDC, HBITMAP *bitmap, int width, int height, int bpp)
+{
+ BITMAPINFO* bmi;
+ BYTE* bits;
+ int palette_count;
+ int obpp = bpp;
+
+ bpp = iGetValidBpp(abs(bpp));
+
+ assert(hDC);
+ assert(width > 0 && height > 0);
+ assert(bpp);
+
+ if (bpp > 8)
+ {
+ if ((bpp == 16 || bpp == 32) && obpp < 0)
+ palette_count = 3;
+ else
+ palette_count = 0;
+ }
+ else
+ palette_count = 1 << bpp;
+
+ bmi = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * palette_count);
+
+ iInitInfoHeader(&bmi->bmiHeader, width, height, bpp, palette_count);
+
+ if (bpp > 8 && palette_count == 3)
+ {
+ DWORD *masks = (DWORD*)(bmi + sizeof(BITMAPINFOHEADER));
+ masks[0] = 0x001F;
+ masks[1] = 0x03E0;
+ masks[2] = 0x7C00;
+ }
+
+ *bitmap = CreateDIBSection(hDC, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+
+ {
+ imDib* dib;
+ dib = imDibCreateReference((BYTE*)bmi, bits);
+ dib->is_reference = 0;
+ return dib;
+ }
+}
+
+
+imDib* imDibCreateCopy(const imDib* src_dib)
+{
+ imDib* dib;
+
+ assert(src_dib);
+
+ dib = (imDib*)malloc(sizeof(imDib));
+
+ memcpy(dib, src_dib, sizeof(imDib));
+
+ AllocDib(dib);
+ if (dib->dib == NULL)
+ {
+ free(dib);
+ return NULL;
+ }
+
+ iInitHeadersReference(dib);
+
+ memcpy(dib->dib, src_dib->dib, dib->size - dib->bits_size);
+
+ iInitBits(dib, NULL);
+
+ memcpy(dib->bits, src_dib->bits, dib->bits_size);
+
+ dib->is_reference = 0;
+
+ return dib;
+}
+
+imDib* imDibCreateReference(BYTE* bmi, BYTE* bits)
+{
+ imDib* dib;
+
+ assert(bmi);
+
+ dib = (imDib*)malloc(sizeof(imDib));
+
+ dib->dib = bmi;
+
+ iInitHeadersReference(dib);
+
+ if (dib->bmih->biBitCount > 8)
+ {
+ dib->palette_count = 0;
+
+ if (dib->bmih->biCompression == BI_BITFIELDS)
+ dib->palette_count = 3;
+ }
+ else
+ {
+ if (dib->bmih->biClrUsed != 0)
+ dib->palette_count = dib->bmih->biClrUsed;
+ else
+ dib->palette_count = 1 << dib->bmih->biBitCount;
+ }
+
+ iInitBits(dib, bits);
+
+ dib->is_reference = 1;
+
+ iInitSizes(dib, dib->bmih->biWidth, abs(dib->bmih->biHeight), dib->bmih->biBitCount);
+
+ return dib;
+}
+
+void imDibDestroy(imDib* dib)
+{
+ assert(dib);
+ if (!dib->is_reference)
+ {
+ GlobalUnlock(dib->handle);
+ GlobalFree(dib->handle);
+ }
+ free(dib);
+}
+
+/*****************
+ Line Acess
+*****************/
+
+imDibLineGetPixel imDibLineGetPixelFunc(int bpp)
+{
+ switch(bpp)
+ {
+ case 1:
+ return &iLineGetPixel1;
+ case 4:
+ return &iLineGetPixel4;
+ case 8:
+ return &iLineGetPixel8;
+ case 16:
+ return &iLineGetPixel16;
+ case 24:
+ return &iLineGetPixel24;
+ case 32:
+ return &iLineGetPixel32;
+ default:
+ if (bpp > 32) return NULL;
+ iGetPixelAnyBpp = bpp;
+ iGetPixelAnyMask = iMakeBitMask(bpp);
+ return &iLineGetPixelAny;
+ }
+}
+
+imDibLineSetPixel imDibLineSetPixelFunc(int bpp)
+{
+ switch(bpp)
+ {
+ case 1:
+ return &iLineSetPixel1;
+ case 4:
+ return &iLineSetPixel4;
+ case 8:
+ return &iLineSetPixel8;
+ case 16:
+ return &iLineSetPixel16;
+ case 24:
+ return &iLineSetPixel24;
+ case 32:
+ return &iLineSetPixel32;
+ default:
+ if (bpp > 32) return NULL;
+ iSetPixelAnyBpp = bpp;
+ iSetPixelAnyMask = iMakeBitMask(bpp);
+ return &iLineSetPixelAny;
+ }
+}
+
+/*****************
+ DIB <-> Bitmap
+*****************/
+
+imDib* imDibFromHBitmap(const HBITMAP bitmap, const HPALETTE hPalette)
+{
+ imDib* dib;
+
+ assert(bitmap);
+
+ {
+ BITMAP bmp;
+
+ if (!GetObject(bitmap, sizeof(BITMAP), (LPSTR)&bmp))
+ return NULL;
+
+ dib = imDibCreate(bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes * bmp.bmBitsPixel);
+ }
+
+ if (!dib)
+ return NULL;
+
+ {
+ HDC ScreenDC = GetDC(NULL);
+ HPALETTE hOldPalette = NULL;
+ if (hPalette) hOldPalette = SelectPalette(ScreenDC, hPalette, FALSE);
+ RealizePalette(ScreenDC);
+
+ GetDIBits(ScreenDC, bitmap, 0, dib->bmih->biHeight, dib->bits, dib->bmi, DIB_RGB_COLORS);
+
+ if (hOldPalette) SelectPalette(ScreenDC, hOldPalette, FALSE);
+ ReleaseDC(NULL, ScreenDC);
+ }
+
+ return dib;
+}
+
+HBITMAP imDibToHBitmap(const imDib* dib)
+{
+ HBITMAP bitmap;
+
+ assert(dib);
+
+ {
+ HDC ScreenDC = GetDC(NULL);
+ bitmap = CreateDIBitmap(ScreenDC, dib->bmih, CBM_INIT, dib->bits, dib->bmi, DIB_RGB_COLORS);
+ ReleaseDC(NULL, ScreenDC);
+ }
+
+/*
+ Another Way
+ bitmap = CreateCompatibleBitmap(ScreenDC, dib->bmih->biWidth, dib->bmih->biHeight);
+ SetDIBits(ScreenDC, bitmap, 0, dib->bmih->biHeight, dib->bits, dib->bmi, DIB_RGB_COLORS);
+*/
+
+ return bitmap;
+}
+
+/*******************
+ DIB <-> Clipboard
+*******************/
+
+int imDibIsClipboardAvailable(void)
+{
+ if (IsClipboardFormatAvailable(CF_DIB) ||
+ IsClipboardFormatAvailable(CF_BITMAP))
+ return 1;
+
+ return 0;
+}
+
+imDib* imDibPasteClipboard(void)
+{
+ int clip_type = 0;
+ if (IsClipboardFormatAvailable(CF_DIB))
+ clip_type = CF_DIB;
+ else if (IsClipboardFormatAvailable(CF_BITMAP))
+ clip_type = CF_BITMAP;
+
+ if (!clip_type)
+ return NULL;
+
+ OpenClipboard(NULL);
+ HANDLE Handle = GetClipboardData(clip_type);
+ if (Handle == NULL)
+ {
+ CloseClipboard();
+ return NULL;
+ }
+
+ imDib *dib;
+ if (clip_type == CF_DIB)
+ {
+ BYTE* bmi = (BYTE*)GlobalLock(Handle);
+ if (!bmi || !iCheckHeader((BITMAPINFOHEADER*)bmi))
+ {
+ CloseClipboard();
+ return NULL;
+ }
+
+ {
+ imDib* clip_dib = imDibCreateReference(bmi, NULL);
+ dib = imDibCreateCopy(clip_dib);
+ imDibDestroy(clip_dib);
+ GlobalUnlock(Handle);
+ }
+ }
+ else
+ {
+ HPALETTE hpal = (HPALETTE)GetClipboardData(CF_PALETTE);
+
+ /* If there is a CF_PALETTE object in the clipboard, this is the palette to assume */
+ /* the bitmap is realized against. */
+ if (!hpal)
+ hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
+
+ dib = imDibFromHBitmap((HBITMAP)Handle, hpal);
+ }
+
+ CloseClipboard();
+
+ return dib;
+}
+
+void imDibCopyClipboard(imDib* dib)
+{
+ assert(dib);
+
+ if (!OpenClipboard(NULL))
+ return;
+ EmptyClipboard();
+ GlobalUnlock(dib->handle);
+ SetClipboardData(CF_DIB, dib->handle);
+ CloseClipboard();
+
+ dib->dib = NULL;
+ dib->is_reference = 1;
+ imDibDestroy(dib);
+}
+
+/*******************
+ DIB -> Palette
+*******************/
+
+HPALETTE imDibLogicalPalette(const imDib* dib)
+{
+ LOGPALETTE* pLogPal;
+ PALETTEENTRY* pPalEntry;
+ HPALETTE hPal;
+ RGBQUAD* bmic;
+ int c;
+
+ assert(dib);
+ assert(dib->bmih->biBitCount <= 8);
+
+ pLogPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + dib->palette_count * sizeof(PALETTEENTRY));
+ pLogPal->palVersion = 0x300;
+ pLogPal->palNumEntries = (WORD)dib->palette_count;
+
+ bmic = dib->bmic;
+ pPalEntry = pLogPal->palPalEntry;
+
+ for (c = 0; c < dib->palette_count; c++)
+ {
+ pPalEntry->peRed = bmic->rgbRed;
+ pPalEntry->peGreen = bmic->rgbGreen;
+ pPalEntry->peBlue = bmic->rgbBlue;
+ pPalEntry->peFlags = PC_NOCOLLAPSE;
+
+ pPalEntry++;
+ bmic++;
+ }
+
+ hPal = CreatePalette(pLogPal);
+ free(pLogPal);
+
+ return hPal;
+}
+
+/*******************
+ DIB <-> RGB Image
+*******************/
+
+void imDibEncodeFromRGBA(imDib* dib, const unsigned char* red, const unsigned char* green, const unsigned char* blue, const unsigned char* alpha)
+{
+ int x, y;
+ BYTE* bits;
+
+ if (dib->bmih->biHeight < 0)
+ bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */
+ else
+ bits = dib->bits;
+
+ assert(dib->bmih->biBitCount > 16);
+
+ for (y = 0; y < abs(dib->bmih->biHeight); y++)
+ {
+ for (x = 0; x < dib->bmih->biWidth; x++)
+ {
+ *bits++ = *blue++;
+ *bits++ = *green++;
+ *bits++ = *red++;
+
+ if (dib->bmih->biBitCount == 32)
+ {
+ if (alpha)
+ *bits++ = *alpha++;
+ else
+ *bits++ = 0xFF; /* opaque */
+ }
+ }
+
+ bits += dib->pad_size;
+
+ if (dib->bmih->biHeight < 0)
+ bits -= 2*dib->line_size;
+ }
+}
+
+void imDibDecodeToRGBA(const imDib* dib, unsigned char* red, unsigned char* green, unsigned char* blue, unsigned char* alpha)
+{
+ int x, y, offset;
+ unsigned short color;
+ BYTE* bits;
+ unsigned int rmask = 0, gmask = 0, bmask = 0,
+ roff = 0, goff = 0, boff = 0; /* pixel bit mask control when reading 16 and 32 bpp images */
+
+ assert(dib);
+ assert(dib->bmih->biBitCount > 8);
+ assert(red && green && blue);
+
+ if (dib->bmih->biHeight < 0)
+ bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */
+ else
+ bits = dib->bits;
+
+ if (dib->bmih->biBitCount == 16)
+ offset = dib->line_size; /* do not increment for each pixel, jump line */
+ else
+ offset = dib->pad_size; /* increment for each pixel, jump pad */
+
+ if (dib->bmih->biCompression == BI_BITFIELDS)
+ {
+ unsigned int Mask;
+ unsigned int* palette = (unsigned int*)dib->bmic;
+
+ rmask = Mask = palette[0];
+ while (!(Mask & 0x01))
+ {Mask >>= 1; roff++;}
+
+ gmask = Mask = palette[1];
+ while (!(Mask & 0x01))
+ {Mask >>= 1; goff++;}
+
+ bmask = Mask = palette[2];
+ while (!(Mask & 0x01))
+ {Mask >>= 1; boff++;}
+ }
+ else if (dib->bmih->biBitCount == 16)
+ {
+ bmask = 0x001F;
+ gmask = 0x03E0;
+ rmask = 0x7C00;
+ boff = 0;
+ goff = 5;
+ roff = 10;
+ }
+
+ for (y = 0; y < abs(dib->bmih->biHeight); y++)
+ {
+ for (x = 0; x < dib->bmih->biWidth; x++)
+ {
+ if (dib->bmih->biBitCount == 16)
+ {
+ color = ((unsigned short*)bits)[x];
+ *red++ = (unsigned char)((((rmask & color) >> roff) * 255) / (rmask >> roff));
+ *green++ = (unsigned char)((((gmask & color) >> goff) * 255) / (gmask >> goff));
+ *blue++ = (unsigned char)((((bmask & color) >> boff) * 255) / (bmask >> boff));
+ }
+ else
+ {
+ *blue++ = *bits++;
+ *green++ = *bits++;
+ *red++ = *bits++;
+
+ if (dib->bmih->biBitCount == 32)
+ {
+ if (alpha)
+ *alpha++ = *bits++;
+ else
+ bits++;
+ }
+ }
+ }
+
+ bits += offset;
+
+ if (dib->bmih->biHeight < 0)
+ bits -= 2*dib->line_size;
+ }
+}
+
+/*******************
+ DIB <-> Map Image
+*******************/
+
+void imDibEncodeFromMap(imDib* dib, const unsigned char* map, const long* palette, int palette_count)
+{
+ assert(dib);
+ assert(map && palette);
+ assert(dib->bmih->biBitCount <= 8);
+ assert(dib->bmih->biCompression != BI_RLE8);
+
+ {
+ int x, y;
+ BYTE* bits;
+
+ if (dib->bmih->biHeight < 0)
+ bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */
+ else
+ bits = dib->bits;
+
+ for (y = 0; y < abs(dib->bmih->biHeight); y++)
+ {
+ for (x = 0; x < dib->bmih->biWidth; x++)
+ bits[x] = *map++;
+
+ if (dib->bmih->biHeight < 0)
+ bits -= dib->line_size;
+ else
+ bits += dib->line_size;
+ }
+ }
+
+ {
+ int c;
+ RGBQUAD* bmic = dib->bmic;
+
+ for (c = 0; c < palette_count; c++)
+ *bmic++ = iLong2Quad(palette[c]);
+ }
+
+ dib->bmih->biClrUsed = palette_count;
+ dib->bmih->biClrImportant = 0;
+ dib->palette_count = palette_count;
+}
+
+void imDibDecodeToMap(const imDib* dib, unsigned char* map, long* palette)
+{
+ assert(dib);
+ assert(dib->bmih->biBitCount <= 8);
+ assert(map && palette);
+
+ {
+ int x, y;
+ BYTE* bits;
+
+ if (dib->bmih->biHeight < 0)
+ bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */
+ else
+ bits = dib->bits;
+
+ for (y = 0; y < abs(dib->bmih->biHeight); y++)
+ {
+ for (x = 0; x < dib->bmih->biWidth; x++)
+ {
+ switch (dib->bmih->biBitCount)
+ {
+ case 1:
+ *map++ = (unsigned char)((bits[x / 8] >> (7 - x % 8)) & 0x01);
+ break;
+ case 4:
+ *map++ = (unsigned char)((bits[x / 2] >> ((1 - x % 2) * 4)) & 0x0F);
+ break;
+ case 8:
+ *map++ = bits[x];
+ break;
+ }
+ }
+
+ if (dib->bmih->biHeight < 0)
+ bits -= dib->line_size;
+ else
+ bits += dib->line_size;
+ }
+ }
+
+ {
+ int c;
+ RGBQUAD* bmic = dib->bmic;
+
+ for (c = 0; c < dib->palette_count; c++)
+ {
+ palette[c] = iQuad2Long(bmic);
+ *bmic++;
+ }
+ }
+}
+
+/*******************
+ DIB <-> File
+*******************/
+
+int imDibSaveFile(const imDib* dib, char* filename)
+{
+ DWORD dwTmp;
+ HANDLE hFile; /* file handle */
+ BITMAPFILEHEADER file_header; /* bitmap file-header */
+
+ assert(dib);
+ assert(filename);
+
+ hFile = CreateFile(filename, GENERIC_WRITE, (DWORD) 0,
+ (LPSECURITY_ATTRIBUTES)NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ return 0;
+
+ /* 0x42 = "B" 0x4d = "M" */
+ file_header.bfType = 0x4d42;
+
+ /* Compute the size of the entire file. */
+ file_header.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dib->palette_count*sizeof(RGBQUAD) + dib->bits_size);
+
+ file_header.bfReserved1 = 0;
+ file_header.bfReserved2 = 0;
+
+ /* Compute the offset to the bits array. */
+ file_header.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dib->palette_count*sizeof(RGBQUAD);
+
+ /* Copy the BITMAPFILEHEADER into the .BMP file. */
+ if (!WriteFile(hFile, (LPVOID)&file_header, sizeof(BITMAPFILEHEADER), (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto save_error;
+
+ /* Copy the BITMAPINFOHEADER into the file. */
+ if (!WriteFile(hFile, (LPVOID)dib->bmih, sizeof(BITMAPINFOHEADER), (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto save_error;
+
+ /* Copy the RGBQUAD array into the file. */
+ if (dib->palette_count > 0)
+ {
+ if (!WriteFile(hFile, (LPVOID)dib->bmic, dib->palette_count*sizeof(RGBQUAD), (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto save_error;
+ }
+
+ /* Copy the bits array into the .BMP file. */
+ if (!WriteFile(hFile, dib->bits, dib->bits_size, (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto save_error;
+
+ /* Close the .BMP file. */
+ CloseHandle(hFile);
+
+ return 1;
+
+save_error:
+ CloseHandle(hFile);
+ return 0;
+}
+
+imDib* imDibLoadFile(const char* filename)
+{
+ HANDLE hFile; /* file handle */
+ DWORD dwTmp;
+ imDib* dib = NULL;
+ BITMAPFILEHEADER file_header; /* bitmap file-header */
+ BITMAPINFOHEADER bmih;
+
+ assert(filename);
+
+ hFile = CreateFile(filename, GENERIC_READ, (DWORD) 0,
+ (LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ /* Read the BITMAPFILEHEADER from the .BMP file. */
+ if (!ReadFile(hFile, (LPVOID)&file_header, sizeof(BITMAPFILEHEADER), (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto load_error;
+
+ if (file_header.bfType != 0x4d42)
+ goto load_error;
+
+ /* Read the BITMAPINFOHEADER from the file. */
+ if (!ReadFile(hFile, (LPVOID)&bmih, sizeof(BITMAPINFOHEADER), (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto load_error;
+
+ if(!iCheckHeader(&bmih))
+ goto load_error;
+
+ dib = imDibCreate(bmih.biWidth, abs(bmih.biHeight), bmih.biCompression==BI_BITFIELDS? -bmih.biBitCount: bmih.biBitCount);
+
+ memcpy(dib->bmih, &bmih, bmih.biSize);
+
+ if (bmih.biSize != sizeof(BITMAPINFOHEADER))
+ {
+ /* skip newer BIH definitions */
+ SetFilePointer(hFile, bmih.biSize - sizeof(BITMAPINFOHEADER), NULL, FILE_CURRENT);
+ dib->bmih->biSize = sizeof(BITMAPINFOHEADER);
+ }
+
+ /* Read the RGBQUAD array from the file. */
+ if (dib->palette_count > 0)
+ {
+ if (!ReadFile(hFile, (LPVOID)dib->bmic, dib->palette_count*sizeof(RGBQUAD), (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto load_error;
+ }
+
+ /* Read the Bits array from the .BMP file. */
+ SetFilePointer(hFile, file_header.bfOffBits, NULL, FILE_BEGIN);
+
+ {
+ int bits_size = dib->bits_size;
+
+ if (bmih.biBitCount < 16 && bmih.biCompression != BI_RGB)
+ bits_size = GetFileSize(hFile, NULL) - file_header.bfOffBits;
+
+ if (bits_size > dib->bits_size)
+ goto load_error;
+
+ if (!ReadFile(hFile, dib->bits, bits_size, (LPDWORD)&dwTmp, (LPOVERLAPPED)NULL))
+ goto load_error;
+ }
+
+ /* Close the .BMP file. */
+ CloseHandle(hFile);
+
+ return dib;
+
+load_error:
+ if (dib) imDibDestroy(dib);
+ CloseHandle(hFile);
+ return NULL;
+}
+
+/*******************
+ Screen -> DIB
+*******************/
+
+imDib* imDibCaptureScreen(int x, int y, int width, int height)
+{
+ HBITMAP bitmap;
+ HDC ScreenDC = GetDC(NULL);
+ HDC hdcCompatible = CreateCompatibleDC(ScreenDC);
+
+ if (width == 0) width = GetDeviceCaps(ScreenDC, HORZRES);
+ if (height == 0) height = GetDeviceCaps(ScreenDC, VERTRES);
+
+ bitmap = CreateCompatibleBitmap(ScreenDC, width, height);
+
+ if (!bitmap)
+ {
+ ReleaseDC(NULL, ScreenDC);
+ return NULL;
+ }
+
+ /* Select the bitmaps into the compatible DC. */
+ SelectObject(hdcCompatible, bitmap);
+
+ /* Copy color data for the entire display into a */
+ /* bitmap that is selected into a compatible DC. */
+ BitBlt(hdcCompatible, 0, 0, width, height, ScreenDC, x, y, SRCCOPY);
+
+ ReleaseDC(NULL, ScreenDC);
+ DeleteDC(hdcCompatible);
+
+ {
+ imDib* dib = imDibFromHBitmap(bitmap, NULL);
+ DeleteObject(bitmap);
+ return dib;
+ }
+}
diff --git a/im/src/im_dibxbitmap.cpp b/im/src/im_dibxbitmap.cpp
new file mode 100755
index 0000000..8fabd4a
--- /dev/null
+++ b/im/src/im_dibxbitmap.cpp
@@ -0,0 +1,181 @@
+/** \file
+ * \brief Conversion between imDib and imImage
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_dibxbitmap.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include <windows.h>
+#include <assert.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_dib.h"
+#include "im_util.h"
+
+
+void imDibEncodeFromBitmap(imDib* dib, const unsigned char* data)
+{
+ int x, y;
+ BYTE* bits;
+
+ assert(dib);
+ assert(dib->bmih->biBitCount > 16);
+ assert(data);
+
+ if (dib->bmih->biHeight < 0)
+ bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */
+ else
+ bits = dib->bits;
+
+ for (y = 0; y < abs(dib->bmih->biHeight); y++)
+ {
+ for (x = 0; x < dib->bmih->biWidth; x++)
+ {
+ *bits++ = *(data+2); // R
+ *bits++ = *(data+1); // G
+ *bits++ = *(data+0); // B
+
+ data += 3;
+
+ if (dib->bmih->biBitCount == 32)
+ *bits++ = *data++;
+ }
+
+ bits += dib->pad_size;
+
+ if (dib->bmih->biHeight < 0)
+ bits -= 2*dib->line_size;
+ }
+}
+
+void imDibDecodeToBitmap(const imDib* dib, unsigned char* data)
+{
+ int x, y, offset;
+ unsigned short color;
+ BYTE* bits;
+ unsigned int rmask = 0, gmask = 0, bmask = 0,
+ roff = 0, goff = 0, boff = 0; /* pixel bit mask control when reading 16 and 32 bpp images */
+
+ assert(dib);
+ assert(dib->bmih->biBitCount > 8);
+ assert(data);
+
+ if (dib->bmih->biHeight < 0)
+ bits = dib->bits + (dib->bits_size - dib->line_size); /* start of last line */
+ else
+ bits = dib->bits;
+
+ if (dib->bmih->biBitCount == 16)
+ offset = dib->line_size; /* do not increment for each pixel, jump line */
+ else
+ offset = dib->pad_size; /* increment for each pixel, jump pad */
+
+ if (dib->bmih->biCompression == BI_BITFIELDS)
+ {
+ unsigned int Mask;
+ unsigned int* palette = (unsigned int*)dib->bmic;
+
+ rmask = Mask = palette[0];
+ while (!(Mask & 0x01))
+ {Mask >>= 1; roff++;}
+
+ gmask = Mask = palette[1];
+ while (!(Mask & 0x01))
+ {Mask >>= 1; goff++;}
+
+ bmask = Mask = palette[2];
+ while (!(Mask & 0x01))
+ {Mask >>= 1; boff++;}
+ }
+ else if (dib->bmih->biBitCount == 16)
+ {
+ bmask = 0x001F;
+ gmask = 0x03E0;
+ rmask = 0x7C00;
+ boff = 0;
+ goff = 5;
+ roff = 10;
+ }
+
+ for (y = 0; y < abs(dib->bmih->biHeight); y++)
+ {
+ for (x = 0; x < dib->bmih->biWidth; x++)
+ {
+ if (dib->bmih->biBitCount == 16)
+ {
+ color = ((unsigned short*)bits)[x];
+ *data++ = (unsigned char)((((rmask & color) >> roff) * 255) / (rmask >> roff));
+ *data++ = (unsigned char)((((gmask & color) >> goff) * 255) / (gmask >> goff));
+ *data++ = (unsigned char)((((bmask & color) >> boff) * 255) / (bmask >> boff));
+ }
+ else
+ {
+ *(data+2) = *bits++; // B
+ *(data+1) = *bits++; // G
+ *(data+0) = *bits++; // R
+
+ data += 3;
+
+ if (dib->bmih->biBitCount == 32)
+ *data++ = *bits++;
+ }
+ }
+
+ bits += offset;
+
+ if (dib->bmih->biHeight < 0)
+ bits -= 2*dib->line_size;
+ }
+}
+
+imImage* imDibToImage(const imDib* dib)
+{
+ assert(dib);
+
+ int color_space = IM_RGB;
+ if (dib->bmih->biBitCount <= 8)
+ color_space = IM_MAP;
+
+ imImage* image = imImageCreate(dib->bmih->biWidth, abs(dib->bmih->biHeight), color_space, IM_BYTE);
+ if (!image)
+ return NULL;
+
+ if (image->color_space == IM_MAP)
+ {
+ image->palette_count = dib->palette_count;
+ imDibDecodeToMap(dib, (imbyte*)image->data[0], image->palette);
+ }
+ else
+ {
+ imDibDecodeToRGBA(dib, (imbyte*)image->data[0], (imbyte*)image->data[1], (imbyte*)image->data[2], NULL);
+ }
+
+ return image;
+}
+
+imDib* imDibFromImage(const imImage* image)
+{
+ assert(image);
+ assert(imImageIsBitmap(image));
+
+ if (!imImageIsBitmap(image))
+ return NULL;
+
+ int bpp;
+ if (image->color_space != IM_RGB)
+ bpp = 8;
+ else
+ bpp = 24;
+
+ imDib* dib = imDibCreate(image->width, image->height, bpp);
+ if (!dib) return NULL;
+
+ if (image->color_space != IM_RGB)
+ imDibEncodeFromMap(dib, (const imbyte*)image->data[0], image->palette, image->palette_count);
+ else
+ imDibEncodeFromRGBA(dib, (const imbyte*)image->data[0], (const imbyte*)image->data[1], (const imbyte*)image->data[2], NULL);
+
+ return dib;
+}
diff --git a/im/src/im_ecw.def b/im/src/im_ecw.def
new file mode 100755
index 0000000..a0c8858
--- /dev/null
+++ b/im/src/im_ecw.def
@@ -0,0 +1,2 @@
+EXPORTS
+ imFormatRegisterECW \ No newline at end of file
diff --git a/im/src/im_ecw.mak b/im/src/im_ecw.mak
new file mode 100755
index 0000000..0894425
--- /dev/null
+++ b/im/src/im_ecw.mak
@@ -0,0 +1,16 @@
+PROJNAME = im
+LIBNAME = im_ecw
+OPT = YES
+
+SRC = im_format_ecw.cpp
+
+ECWSDKINC = d:/lng/ecw_sdk/include
+ECWSDKLIB = d:/lng/ecw_sdk/lib/$(TEC_UNAME)
+
+INCLUDES = ../include $(ECWSDKINC)
+
+LDIR = $(ECWSDKLIB)
+LIBS = NCSEcw
+
+IM = ..
+USE_IM = Yes
diff --git a/im/src/im_file.cpp b/im/src/im_file.cpp
new file mode 100755
index 0000000..3bfa779
--- /dev/null
+++ b/im/src/im_file.cpp
@@ -0,0 +1,465 @@
+/** \file
+ * \brief File Access
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_file.cpp,v 1.5 2009/08/23 23:57:51 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "im.h"
+#include "im_format.h"
+#include "im_util.h"
+#include "im_attrib.h"
+#include "im_counter.h"
+#include "im_plus.h" // make shure that this file is compiled
+
+
+void imFileClear(imFile* ifile)
+{
+ // can not reset compression and image_count
+
+ ifile->is_new = 0;
+ ifile->attrib_table = 0;
+
+ ifile->line_buffer = 0;
+ ifile->line_buffer_size = 0;
+ ifile->line_buffer_extra = 0;
+ ifile->line_buffer_alloc = 0;
+
+ ifile->convert_bpp = 0;
+ ifile->switch_type = 0;
+
+ ifile->width = 0;
+ ifile->height = 0;
+ ifile->image_index = -1;
+ ifile->user_data_type = 0;
+ ifile->user_color_mode = 0;
+ ifile->file_data_type = 0;
+ ifile->file_color_mode = 0;
+
+ ifile->palette_count = 256;
+ for (int i = 0; i < 256; i++)
+ ifile->palette[i] = imColorEncode((imbyte)i, (imbyte)i, (imbyte)i);
+}
+
+void imFileSetBaseAttributes(imFile* ifile)
+{
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+ imAttribTable* atable = (imAttribTable*)ifileformat->attrib_table;
+
+ atable->Set("FileFormat", IM_BYTE, -1, ifileformat->iformat->format);
+ atable->Set("FileCompression", IM_BYTE, -1, ifileformat->compression);
+ atable->Set("FileImageCount", IM_INT, 1, &ifileformat->image_count);
+}
+
+imFile* imFileOpen(const char* file_name, int *error)
+{
+ assert(file_name);
+
+ imFileFormatBase* ifileformat = imFileFormatBaseOpen(file_name, error);
+ if (!ifileformat)
+ return NULL;
+
+ imFileClear(ifileformat);
+
+ ifileformat->attrib_table = new imAttribTable(599);
+ imFileSetBaseAttributes(ifileformat);
+
+ ifileformat->counter = imCounterBegin(file_name);
+
+ return ifileformat;
+}
+
+imFile* imFileOpenAs(const char* file_name, const char* format, int *error)
+{
+ assert(file_name);
+
+ imFileFormatBase* ifileformat = imFileFormatBaseOpenAs(file_name, format, error);
+ if (!ifileformat)
+ return NULL;
+
+ imFileClear(ifileformat);
+
+ ifileformat->attrib_table = new imAttribTable(599);
+ imFileSetBaseAttributes(ifileformat);
+
+ ifileformat->counter = imCounterBegin(file_name);
+
+ return ifileformat;
+}
+
+imFile* imFileNew(const char* file_name, const char* format, int *error)
+{
+ assert(file_name);
+
+ imFileFormatBase* ifileformat = imFileFormatBaseNew(file_name, format, error);
+ if (!ifileformat)
+ return NULL;
+
+ imFileClear(ifileformat);
+
+ ifileformat->is_new = 1;
+ ifileformat->image_count = 0;
+ ifileformat->compression[0] = 0;
+
+ ifileformat->attrib_table = new imAttribTable(101);
+
+ ifileformat->counter = imCounterBegin(file_name);
+
+ return ifileformat;
+}
+
+void imFileClose(imFile* ifile)
+{
+ assert(ifile);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+ imAttribTable* attrib_table = (imAttribTable*)ifile->attrib_table;
+
+ imCounterEnd(ifile->counter);
+
+ ifileformat->Close();
+
+ if (ifile->line_buffer) free(ifile->line_buffer);
+
+ delete attrib_table;
+}
+
+void* imFileHandle(imFile* ifile, int index)
+{
+ assert(ifile);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+ return ifileformat->Handle(index);
+}
+
+void imFileSetAttribute(imFile* ifile, const char* attrib, int data_type, int count, const void* data)
+{
+ assert(ifile);
+ assert(attrib);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+ imAttribTable* atable = (imAttribTable*)ifileformat->attrib_table;
+ if (data)
+ atable->Set(attrib, data_type, count, data);
+ else
+ atable->UnSet(attrib);
+}
+
+const void* imFileGetAttribute(imFile* ifile, const char* attrib, int *data_type, int *count)
+{
+ assert(ifile);
+ assert(attrib);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+ imAttribTable* attrib_table = (imAttribTable*)ifileformat->attrib_table;
+ return attrib_table->Get(attrib, data_type, count);
+}
+
+static int iAttribCB(void* user_data, int index, const char* name, int data_type, int count, const void* data)
+{
+ (void)data_type;
+ (void)data;
+ (void)count;
+ char** attrib = (char**)user_data;
+ attrib[index] = (char*)name;
+ return 1;
+}
+
+void imFileGetAttributeList(imFile* ifile, char** attrib, int *attrib_count)
+{
+ assert(ifile);
+ assert(attrib_count);
+
+ imAttribTable* attrib_table = (imAttribTable*)ifile->attrib_table;
+ *attrib_count = attrib_table->Count();
+
+ if (attrib) attrib_table->ForEach((void*)attrib, iAttribCB);
+}
+
+void imFileGetInfo(imFile* ifile, char* format, char* compression, int *image_count)
+{
+ assert(ifile);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+
+ if(compression) strcpy(compression, ifile->compression);
+ if(format) strcpy(format, ifileformat->iformat->format);
+ if (image_count) *image_count = ifile->image_count;
+}
+
+static int iFileCheckPaletteGray(imFile* ifile)
+{
+ int i;
+ imbyte r, g, b;
+ imbyte remaped[256];
+ memset(remaped, 0, 256);
+
+ for (i = 0; i < ifile->palette_count; i++)
+ {
+ imColorDecode(&r, &g, &b, ifile->palette[i]);
+
+ /* if there are colors abort */
+ if (r != g || g != b)
+ return 0;
+
+ /* grays out of order, will be remapped, but must be unique,
+ if there are duplicates maybe they are used for different pourposes */
+ if (i != r)
+ {
+ if (!remaped[r])
+ remaped[r] = 1;
+ else
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int iFileCheckPaletteBinary(imFile* ifile)
+{
+ if (ifile->palette_count > 2)
+ return 0;
+
+ imbyte r, g, b;
+
+ imColorDecode(&r, &g, &b, ifile->palette[0]);
+ if ((r != 0 || g != 0 || b != 0) &&
+ (r != 1 || g != 1 || b != 1) &&
+ (r != 255 || g != 255 || b != 255))
+ return 0;
+
+ imColorDecode(&r, &g, &b, ifile->palette[1]);
+ if ((r != 0 || g != 0 || b != 0) &&
+ (r != 1 || g != 1 || b != 1) &&
+ (r != 255 || g != 255 || b != 255))
+ return 0;
+
+ return 1;
+}
+
+int imFileReadImageInfo(imFile* ifile, int index, int *width, int *height, int *file_color_mode, int *file_data_type)
+{
+ assert(ifile);
+ assert(!ifile->is_new);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+
+ if (index >= ifile->image_count)
+ return IM_ERR_DATA;
+
+ if (ifile->image_index != -1 &&
+ ifile->image_index == index)
+ {
+ if(width) *width = ifile->width;
+ if(height) *height = ifile->height;
+ if(file_color_mode) *file_color_mode = ifile->file_color_mode;
+ if(file_data_type) *file_data_type = ifile->file_data_type;
+
+ return IM_ERR_NONE;
+ }
+
+ ifile->convert_bpp = 0;
+ ifile->switch_type = 0;
+
+ int error = ifileformat->ReadImageInfo(index);
+ if (error) return error;
+
+ if (!imImageCheckFormat(ifile->file_color_mode, ifile->file_data_type))
+ return IM_ERR_DATA;
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_BINARY)
+ {
+ ifile->palette_count = 2;
+ ifile->palette[0] = imColorEncode(0, 0, 0);
+ ifile->palette[1] = imColorEncode(255, 255, 255);
+ }
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_MAP)
+ {
+ if (iFileCheckPaletteGray(ifile))
+ ifile->file_color_mode = (ifile->file_color_mode & 0xFF00) | IM_GRAY;
+
+ if (iFileCheckPaletteBinary(ifile))
+ ifile->file_color_mode = (ifile->file_color_mode & 0xFF00) | IM_BINARY;
+ }
+
+ if(width) *width = ifile->width;
+ if(height) *height = ifile->height;
+ if(file_color_mode) *file_color_mode = ifile->file_color_mode;
+ if(file_data_type) *file_data_type = ifile->file_data_type;
+
+ ifile->image_index = index;
+
+ return IM_ERR_NONE;
+}
+
+void imFileGetPalette(imFile* ifile, long* palette, int *palette_count)
+{
+ assert(ifile);
+ assert(palette);
+
+ if (ifile->palette_count != 0 && palette)
+ memcpy(palette, ifile->palette, ifile->palette_count*sizeof(long));
+
+ if (palette_count) *palette_count = ifile->palette_count;
+}
+
+static void iFileCheckConvertGray(imFile* ifile, imbyte* data)
+{
+ int i, do_remap = 0;
+ imbyte remap[256], r, g, b;
+
+ // enforce the palette to only have grays in the correct order.
+
+ for (i = 0; i < ifile->palette_count; i++)
+ {
+ imColorDecode(&r, &g, &b, ifile->palette[i]);
+
+ if (r != i)
+ {
+ ifile->palette[i] = imColorEncode((imbyte)i, (imbyte)i, (imbyte)i);
+ do_remap = 1;
+ }
+
+ remap[i] = r;
+ }
+
+ if (!do_remap)
+ return;
+
+ int count = ifile->width*ifile->height;
+ for(i = 0; i < count; i++)
+ {
+ *data = remap[*data];
+ data++;
+ }
+
+ int transp_count;
+ imbyte* transp_map = (imbyte*)imFileGetAttribute(ifile, "TransparencyMap", NULL, &transp_count);
+ if (transp_map)
+ {
+ imbyte new_transp_map[256];
+ for (i=0; i<transp_count; i++)
+ new_transp_map[i] = transp_map[remap[i]];
+ imFileSetAttribute(ifile, "TransparencyMap", IM_BYTE, transp_count, new_transp_map);
+ }
+}
+
+static void iFileCheckConvertBinary(imFile* ifile, imbyte* data)
+{
+ int count = ifile->width*ifile->height;
+ for(int i = 0; i < count; i++)
+ {
+ if (*data)
+ *data = 1;
+ data++;
+ }
+}
+
+int imFileReadImageData(imFile* ifile, void* data, int convert2bitmap, int color_mode_flags)
+{
+ assert(ifile);
+ assert(!ifile->is_new);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+
+ if (ifile->image_index == -1)
+ return IM_ERR_DATA;
+
+ ifile->user_color_mode = ifile->file_color_mode;
+ ifile->user_data_type = ifile->file_data_type;
+
+ if (convert2bitmap)
+ {
+ ifile->user_data_type = IM_BYTE;
+ ifile->user_color_mode = imColorModeToBitmap(ifile->file_color_mode);
+ }
+
+ if (color_mode_flags != -1)
+ {
+ ifile->user_color_mode = imColorModeSpace(ifile->user_color_mode);
+ ifile->user_color_mode |= color_mode_flags;
+ }
+
+ if (!imImageCheckFormat(ifile->user_color_mode, ifile->user_data_type))
+ return IM_ERR_DATA;
+
+ if (!imFileCheckConversion(ifile))
+ return IM_ERR_DATA;
+
+ imFileLineBufferInit(ifile);
+
+ int ret = ifileformat->ReadImageData(data);
+
+ // here we can NOT change the file_color_mode we already returned to the user
+ // so just check for gray and binary consistency
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_GRAY && ifile->file_data_type == IM_BYTE)
+ iFileCheckConvertGray(ifile, (imbyte*)data);
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_BINARY)
+ iFileCheckConvertBinary(ifile, (imbyte*)data);
+
+ return ret;
+}
+
+void imFileSetInfo(imFile* ifile, const char* compression)
+{
+ assert(ifile);
+ assert(ifile->is_new);
+
+ if (!compression)
+ ifile->compression[0] = 0;
+ else
+ strcpy(ifile->compression, compression);
+}
+
+void imFileSetPalette(imFile* ifile, long* palette, int palette_count)
+{
+ assert(ifile);
+ assert(palette);
+ assert(palette_count != 0);
+
+ memcpy(ifile->palette, palette, palette_count*sizeof(long));
+ ifile->palette_count = palette_count;
+}
+
+int imFileWriteImageInfo(imFile* ifile, int width, int height, int user_color_mode, int user_data_type)
+{
+ assert(ifile);
+ assert(ifile->is_new);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+
+ if (!imImageCheckFormat(user_color_mode, user_data_type))
+ return IM_ERR_DATA;
+
+ int error = ifileformat->iformat->CanWrite(ifile->compression, user_color_mode, user_data_type);
+ if (error) return error;
+
+ ifile->width = width;
+ ifile->height = height;
+ ifile->user_color_mode = user_color_mode;
+ ifile->user_data_type = user_data_type;
+
+ if (imColorModeSpace(user_color_mode) == IM_BINARY)
+ {
+ ifile->palette_count = 2;
+ ifile->palette[0] = imColorEncode(0, 0, 0);
+ ifile->palette[1] = imColorEncode(255, 255, 255);
+ }
+
+ return ifileformat->WriteImageInfo();
+}
+
+int imFileWriteImageData(imFile* ifile, void* data)
+{
+ assert(ifile);
+ assert(ifile->is_new);
+ assert(data);
+ imFileFormatBase* ifileformat = (imFileFormatBase*)ifile;
+
+ if (!imFileCheckConversion(ifile))
+ return IM_ERR_DATA;
+
+ imFileLineBufferInit(ifile);
+
+ return ifileformat->WriteImageData(data);
+}
diff --git a/im/src/im_filebuffer.cpp b/im/src/im_filebuffer.cpp
new file mode 100755
index 0000000..09c5ad4
--- /dev/null
+++ b/im/src/im_filebuffer.cpp
@@ -0,0 +1,695 @@
+/** \file
+ * \brief File Access - Buffer Management
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_filebuffer.cpp,v 1.2 2009/08/13 22:34:25 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "im.h"
+#include "im_format.h"
+#include "im_util.h"
+#include "im_complex.h"
+#include "im_color.h"
+
+
+int imFileLineSizeAligned(int width, int bpp, int align)
+{
+ if (align == 4)
+ return ((width * bpp + 31) / 32) * 4;
+ else if (align == 2)
+ return ((width * bpp + 15) / 16) * 2;
+ else
+ return (width * bpp + 7) / 8;
+}
+
+template <class T>
+static void iDoFillLineBuffer(int width, int height, int line, int plane,
+ int file_color_mode, T* line_buffer,
+ int user_color_mode, const T* data)
+{
+ // (writing) from data to file
+ // will handle packing and alpha
+
+ int file_depth = imColorModeDepth(file_color_mode);
+ int data_depth = imColorModeDepth(user_color_mode);
+ int data_plane_size = width*height; // This will be used in UNpacked data
+
+ if (imColorModeIsPacked(user_color_mode))
+ data += line*width*data_depth;
+ else
+ data += line*width;
+
+ for (int x = 0; x < width; x++)
+ {
+ int x_data_offset = x*data_depth; // This will be used in packed data
+
+ if (imColorModeIsPacked(file_color_mode))
+ {
+ int x_file_offset = x*file_depth; // This will be used in packed data
+
+ // file is packed
+ // NO color space conversion, color_space must match
+ // Ignore alpha if necessary.
+ int depth = IM_MIN(file_depth, data_depth);
+ for (int d = 0; d < depth; d++)
+ {
+ if (imColorModeIsPacked(user_color_mode))
+ line_buffer[x_file_offset + d] = data[x_data_offset + d];
+ else
+ line_buffer[x_file_offset + d] = data[d*data_plane_size + x];
+ }
+ }
+ else
+ {
+ // file NOT packed, copy just one plane
+ // NO color space conversion, color_space must match
+
+ if (plane >= imColorModeDepth(user_color_mode))
+ return;
+
+ if (imColorModeIsPacked(user_color_mode))
+ line_buffer[x] = data[x_data_offset + plane];
+ else
+ line_buffer[x] = data[plane*data_plane_size + x];
+ }
+ }
+}
+
+template <class T>
+static void iDoFillData(int width, int height, int line, int plane,
+ int file_color_mode, const T* line_buffer,
+ int user_color_mode, T* data)
+{
+ // (reading) from file to data
+ // will handle packing and alpha
+
+ int file_depth = imColorModeDepth(file_color_mode);
+ int data_depth = imColorModeDepth(user_color_mode);
+ int data_plane_size = width*height; // This will be used in UNpacked data
+
+ if (imColorModeIsPacked(user_color_mode))
+ data += line*width*data_depth;
+ else
+ data += line*width;
+
+ for (int x = 0; x < width; x++)
+ {
+ int x_data_offset = x*data_depth; // This will be used in packed data
+
+ if (imColorModeIsPacked(file_color_mode))
+ {
+ int x_file_offset = x*file_depth; // This will be used in packed data
+
+ // file is packed
+ // NO color space conversion, color_space must match
+ // ignore alpha if necessary.
+ int depth = IM_MIN(file_depth, data_depth);
+ for (int d = 0; d < depth; d++)
+ {
+ if (imColorModeIsPacked(user_color_mode))
+ data[x_data_offset + d] = line_buffer[x_file_offset + d];
+ else
+ data[d*data_plane_size + x] = line_buffer[x_file_offset + d];
+ }
+ }
+ else
+ {
+ // file NOT packed, copy just one plane
+ // NO color space conversion, color_space must match
+
+ if (plane >= imColorModeDepth(user_color_mode))
+ return;
+
+ if (imColorModeIsPacked(user_color_mode))
+ data[x_data_offset + plane] = line_buffer[x];
+ else
+ data[plane*data_plane_size + x] = line_buffer[x];
+ }
+ }
+}
+
+template <class T>
+static inline void iConvertColor2RGB(T* data, int color_space, int data_type)
+{
+ T zero, max = (T)imColorMax(data_type);
+
+ // These are identical procedures to iDoConvert2RGB in "im_filebuffer.cpp".
+
+ switch (color_space)
+ {
+ case IM_XYZ:
+ {
+ // to increase precision do intermediate conversions in float
+
+ // scale to 0-1
+ float c0 = imColorReconstruct(data[0], max);
+ float c1 = imColorReconstruct(data[1], max);
+ float c2 = imColorReconstruct(data[2], max);
+
+ // result is still 0-1
+ imColorXYZ2RGB(c0, c1, c2,
+ c0, c1, c2, 1.0f);
+
+ // do gamma correction then scale back to 0-max
+ data[0] = imColorQuantize(imColorTransfer2Nonlinear(c0), max);
+ data[1] = imColorQuantize(imColorTransfer2Nonlinear(c1), max);
+ data[2] = imColorQuantize(imColorTransfer2Nonlinear(c2), max);
+ }
+ break;
+ case IM_YCBCR:
+ zero = (T)imColorZero(data_type);
+ imColorYCbCr2RGB(data[0], data[1], data[2],
+ data[0], data[1], data[2], zero, max);
+ break;
+ case IM_CMYK:
+ imColorCMYK2RGB(data[0], data[1], data[2], data[3],
+ data[0], data[1], data[2], max);
+ break;
+ case IM_LUV:
+ case IM_LAB:
+ {
+ // to increase precision do intermediate conversions in float
+ // scale to 0-1 and -0.5/+0.5
+ float c0 = imColorReconstruct(data[0], max);
+ float c1 = imColorReconstruct(data[1], max) - 0.5f;
+ float c2 = imColorReconstruct(data[2], max) - 0.5f;
+
+ if (color_space == IM_LUV)
+ imColorLuv2XYZ(c0, c1, c2, // conversion in-place
+ c0, c1, c2);
+ else
+ imColorLab2XYZ(c0, c1, c2, // conversion in-place
+ c0, c1, c2);
+
+ imColorXYZ2RGB(c0, c1, c2, // conversion in-place
+ c0, c1, c2, 1.0f);
+
+ // do gamma correction then scale back to 0-max
+ data[0] = imColorQuantize(imColorTransfer2Nonlinear(c0), max);
+ data[1] = imColorQuantize(imColorTransfer2Nonlinear(c1), max);
+ data[2] = imColorQuantize(imColorTransfer2Nonlinear(c2), max);
+ }
+ break;
+ }
+}
+
+// These functions will be always converting RGB -> RGB (0-max) -> (0-255)
+
+static inline imbyte iConvertType2Byte(const imbyte& data)
+ { return data; }
+
+static inline imbyte iConvertType2Byte(const imushort& data)
+ { return imColorQuantize(imColorReconstruct(data, (imushort)65535), (imbyte)255); }
+
+static inline imbyte iConvertType2Byte(const int& data)
+ { return imColorQuantize(imColorReconstruct(data, 16777215), (imbyte)255); }
+
+static inline imbyte iConvertType2Byte(const float& data)
+ { return imColorQuantize(data, (imbyte)255); }
+
+// Fake float to avoid erros in the color conversion template rotines.
+// Since the color conversion use the double value, they are invalid,
+// so the automatic conversion to bitmap for complex images works only for RGB.
+static inline imbyte iConvertType2Byte(const double& data)
+{
+ imcfloat* fdata = (imcfloat*)&data;
+ return imColorQuantize(cpxmag(*fdata), (imbyte)255);
+}
+
+template <class T>
+static void iDoFillDataBitmap(int width, int height, int line, int plane, int data_type,
+ int file_color_mode, const T* line_buffer,
+ int user_color_mode, imbyte* data)
+{
+ // (reading) from file to data
+ // will handle packing, alpha, color space conversion to RGB and data_type to BYTE
+
+ int file_depth = imColorModeDepth(file_color_mode);
+ int data_depth = imColorModeDepth(user_color_mode);
+ int copy_alpha = imColorModeHasAlpha(file_color_mode) && imColorModeHasAlpha(user_color_mode);
+ int data_plane_size = width*height; // This will be used in UNpacked data
+
+ if (imColorModeIsPacked(user_color_mode))
+ data += line*width*data_depth;
+ else
+ data += line*width;
+
+ for (int x = 0; x < width; x++)
+ {
+ int x_data_offset = x*data_depth; // This will be used in packed data
+
+ if (imColorModeIsPacked(file_color_mode))
+ {
+ int x_file_offset = x*file_depth; // This will be used in packed data
+
+ if (imColorModeMatch(file_color_mode, user_color_mode))
+ {
+ // file is packed
+ // same color space components (in this case means RGB)
+ // ignore alpha if necessary.
+ int depth = IM_MIN(file_depth, data_depth);
+ for (int d = 0; d < depth; d++)
+ {
+ if (imColorModeIsPacked(user_color_mode))
+ data[x_data_offset + d] = iConvertType2Byte(line_buffer[x_file_offset + d]);
+ else
+ data[d*data_plane_size + x] = iConvertType2Byte(line_buffer[x_file_offset + d]);
+ }
+ }
+ else
+ {
+ // file is packed
+ // but different color space components
+ // only to RGB conversions are accepted
+
+ if (imColorModeSpace(user_color_mode) != IM_RGB)
+ return;
+
+ T src_data[4];
+ src_data[0] = line_buffer[x_file_offset];
+ src_data[1] = line_buffer[x_file_offset + 1];
+ src_data[2] = line_buffer[x_file_offset + 2];
+ if (imColorModeSpace(file_color_mode) == IM_CMYK)
+ src_data[3] = line_buffer[x_file_offset + 3];
+
+ // Do conversion in place
+ iConvertColor2RGB(src_data, imColorModeSpace(file_color_mode), data_type);
+
+ if (imColorModeIsPacked(user_color_mode))
+ {
+ data[x_data_offset] = iConvertType2Byte(src_data[0]);
+ data[x_data_offset + 1] = iConvertType2Byte(src_data[1]);
+ data[x_data_offset + 2] = iConvertType2Byte(src_data[2]);
+
+ if (copy_alpha)
+ {
+ if (imColorModeSpace(file_color_mode) == IM_CMYK)
+ data[x_data_offset + 3] = iConvertType2Byte(line_buffer[x_file_offset + 4]);
+ else
+ data[x_data_offset + 3] = iConvertType2Byte(line_buffer[x_file_offset + 3]);
+ }
+ }
+ else
+ {
+ data[x] = iConvertType2Byte(src_data[0]);
+ data[data_plane_size + x] = iConvertType2Byte(src_data[1]);
+ data[2*data_plane_size + x] = iConvertType2Byte(src_data[2]);
+
+ if (copy_alpha)
+ {
+ if (imColorModeSpace(file_color_mode) == IM_CMYK)
+ data[3*data_plane_size + x] = iConvertType2Byte(line_buffer[x_file_offset + 4]);
+ else
+ data[3*data_plane_size + x] = iConvertType2Byte(line_buffer[x_file_offset + 3]);
+ }
+ }
+ }
+ }
+ else
+ {
+ // file NOT packed, copy just one plane
+ // NO color space conversion possible now
+
+ if (plane >= imColorModeDepth(user_color_mode))
+ return;
+
+ if (imColorModeIsPacked(user_color_mode))
+ data[x_data_offset + plane] = iConvertType2Byte(line_buffer[x]);
+ else
+ data[plane*data_plane_size + x] = iConvertType2Byte(line_buffer[x]);
+ }
+ }
+}
+
+static void iFileExpandBits(imFile* ifile)
+{
+ // conversion will be done in place in backward order (from end to start)
+
+ if (abs(ifile->convert_bpp) < 8)
+ {
+ imbyte* byte_buffer = (imbyte*)ifile->line_buffer;
+ imbyte* bit_buffer = (imbyte*)ifile->line_buffer;
+
+ byte_buffer += ifile->width-1;
+ int bpp = ifile->convert_bpp;
+ int expand_range = imColorModeSpace(ifile->file_color_mode) == IM_GRAY? 1: 0;
+
+ for (int i=ifile->width-1; i >= 0; i--)
+ {
+ if (bpp == 1)
+ *byte_buffer = (imbyte)((bit_buffer[i / 8] >> (7 - i % 8)) & 0x01);
+ else if (bpp == 4)
+ *byte_buffer = (imbyte)((bit_buffer[i / 2] >> ((1 - i % 2) * 4)) & 0x0F);
+ else if (bpp == 2)
+ *byte_buffer = (imbyte)((bit_buffer[i / 4] >> ((3 - i % 4) * 2)) & 0x03);
+
+ if (expand_range) /* if convert_bpp<0 then only expand its range */
+ {
+ if (bpp == 4 || bpp == -4)
+ *byte_buffer *= 17;
+ else if (bpp == 2 || bpp == -2)
+ *byte_buffer *= 85;
+ }
+
+ byte_buffer--;
+ }
+ }
+ else if (ifile->convert_bpp == 12)
+ {
+ imushort* ushort_buffer = (imushort*)ifile->line_buffer;
+ imbyte* bit_buffer = (imbyte*)ifile->line_buffer;
+
+ for (int i=ifile->width-1; i >= 0; i--)
+ {
+ int byte_index = (3*i)/2;
+ if (i%2)
+ ushort_buffer[i] = (bit_buffer[byte_index] << 4) | (bit_buffer[byte_index+1] & 0x0F);
+ else
+ ushort_buffer[i] = ((bit_buffer[byte_index] & 0x0F) << 8) | (bit_buffer[byte_index+1]);
+ }
+ }
+}
+
+static void iFileCompactBits(imFile* ifile)
+{
+ // conversion will be done in place
+ imbyte* byte_buffer = (imbyte*)ifile->line_buffer;
+ imbyte* bit_buffer = (imbyte*)ifile->line_buffer;
+
+ if (ifile->convert_bpp == 1)
+ {
+ for (int i = 0; i < ifile->width; i++)
+ {
+ if (*byte_buffer)
+ bit_buffer[i / 8] |= (0x01 << (7 - (i % 8)));
+ else
+ bit_buffer[i / 8] &= ~(0x01 << (7 - (i % 8)));
+
+ byte_buffer++;
+ }
+ }
+ else // -1 == expand 1 to 255
+ {
+ for (int i = 0; i < ifile->width; i++)
+ {
+ if (*byte_buffer)
+ *byte_buffer = 255;
+
+ byte_buffer++;
+ }
+ }
+}
+
+template <class SRC, class DST>
+static void iDoSwitchInt(int count, const SRC* src_data, DST* dst_data, int offset)
+{
+ for (int i = 0; i < count; i++)
+ {
+ *dst_data++ = (DST)((int)*src_data++ + offset);
+ }
+}
+
+template <class SRC, class DST>
+static void iDoSwitchReal(int count, const SRC* src_data, DST* dst_data)
+{
+ for (int i = 0; i < count; i++)
+ {
+ *dst_data++ = (DST)(*src_data++);
+ }
+}
+
+static void iFileSwitchFromType(imFile* ifile)
+{
+ int line_count = imImageLineCount(ifile->width, ifile->file_color_mode);
+ switch(ifile->file_data_type)
+ {
+ case IM_BYTE: // Source is char
+ iDoSwitchInt(line_count, (const char*)ifile->line_buffer, (imbyte*)ifile->line_buffer, 128);
+ break;
+ case IM_USHORT: // Source is short
+ iDoSwitchInt(line_count, (const short*)ifile->line_buffer, (imushort*)ifile->line_buffer, 32768);
+ break;
+ case IM_INT: // Source is uint
+ iDoSwitchInt(line_count, (const unsigned int*)ifile->line_buffer, (int*)ifile->line_buffer, -8388608);
+ break;
+ case IM_FLOAT: // Source is double
+ iDoSwitchReal(line_count, (const double*)ifile->line_buffer, (float*)ifile->line_buffer);
+ break;
+ case IM_CFLOAT: // Source is complex double
+ iDoSwitchReal(2*line_count, (const double*)ifile->line_buffer, (float*)ifile->line_buffer);
+ break;
+ }
+}
+
+static void iFileSwitchToType(imFile* ifile)
+{
+ int line_count = imImageLineCount(ifile->width, ifile->file_color_mode);
+ switch(ifile->file_data_type)
+ {
+ case IM_BYTE: // Destiny is char
+ iDoSwitchInt(line_count, (const imbyte*)ifile->line_buffer, (char*)ifile->line_buffer, -128);
+ break;
+ case IM_USHORT: // Destiny is short
+ iDoSwitchInt(line_count, (const imushort*)ifile->line_buffer, (short*)ifile->line_buffer, -32768);
+ break;
+ case IM_INT: // Destiny is uint
+ iDoSwitchInt(line_count, (const int*)ifile->line_buffer, (unsigned int*)ifile->line_buffer, 8388608);
+ break;
+ case IM_FLOAT: // Destiny is double
+ iDoSwitchReal(line_count, (const float*)ifile->line_buffer, (double*)ifile->line_buffer);
+ break;
+ case IM_CFLOAT: // Destiny is complex double
+ iDoSwitchReal(2*line_count, (const float*)ifile->line_buffer, (double*)ifile->line_buffer);
+ break;
+ }
+}
+
+void imFileLineBufferWrite(imFile* ifile, const void* data, int line, int plane)
+{
+ // (writing) from data to file
+
+ if (imColorModeIsTopDown(ifile->file_color_mode) != imColorModeIsTopDown(ifile->user_color_mode))
+ line = ifile->height-1 - line;
+
+ if ((ifile->file_color_mode & 0x3FF) ==
+ (ifile->user_color_mode & 0x3FF)) // compare only packing, alpha and color space
+ {
+ int data_offset = line*ifile->line_buffer_size;
+ if (plane != 0)
+ data_offset += plane*ifile->height*ifile->line_buffer_size;
+
+ memcpy(ifile->line_buffer, (unsigned char*)data + data_offset, ifile->line_buffer_size);
+ }
+ else
+ {
+ switch(ifile->file_data_type)
+ {
+ case IM_BYTE:
+ iDoFillLineBuffer(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (imbyte*)ifile->line_buffer,
+ ifile->user_color_mode, (const imbyte*)data);
+ break;
+ case IM_USHORT:
+ iDoFillLineBuffer(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (imushort*)ifile->line_buffer,
+ ifile->user_color_mode, (const imushort*)data);
+ break;
+ case IM_INT:
+ iDoFillLineBuffer(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (int*)ifile->line_buffer,
+ ifile->user_color_mode, (const int*)data);
+ break;
+ case IM_FLOAT:
+ iDoFillLineBuffer(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (float*)ifile->line_buffer,
+ ifile->user_color_mode, (const float*)data);
+ break;
+ case IM_CFLOAT:
+ iDoFillLineBuffer(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (imcfloat*)ifile->line_buffer,
+ ifile->user_color_mode, (const imcfloat*)data);
+ break;
+ }
+ }
+
+ if (ifile->convert_bpp)
+ iFileCompactBits(ifile);
+
+ if (ifile->switch_type)
+ iFileSwitchToType(ifile);
+}
+
+void imFileLineBufferRead(imFile* ifile, void* data, int line, int plane)
+{
+ // (reading) from file to data
+
+ if (imColorModeIsTopDown(ifile->file_color_mode) != imColorModeIsTopDown(ifile->user_color_mode))
+ line = ifile->height-1 - line;
+
+ if (ifile->convert_bpp)
+ iFileExpandBits(ifile);
+
+ if (ifile->switch_type)
+ iFileSwitchFromType(ifile);
+
+ if ((ifile->file_color_mode & 0x3FF) == (ifile->user_color_mode & 0x3FF) && // compare only packing, alpha and color space, ignore bottom up.
+ ifile->file_data_type == ifile->user_data_type) // compare data type when reading
+ {
+ int data_offset = line*ifile->line_buffer_size;
+ if (plane != 0)
+ data_offset += plane*ifile->height*ifile->line_buffer_size;
+
+ memcpy((unsigned char*)data + data_offset, ifile->line_buffer, ifile->line_buffer_size);
+ }
+ else
+ {
+ // now we have 2 conversions groups
+ // one to convert only packing and alpha
+ // and the other to convert packing, alpha, color space and data type
+ int convert2bitmap = 0;
+ if (imColorModeSpace(ifile->user_color_mode) != imColorModeSpace(ifile->file_color_mode) ||
+ ifile->file_data_type != IM_BYTE)
+ convert2bitmap = 1;
+
+ switch(ifile->file_data_type)
+ {
+ case IM_BYTE:
+ if (convert2bitmap)
+ iDoFillDataBitmap(ifile->width, ifile->height, line, plane, ifile->file_data_type,
+ ifile->file_color_mode, (const imbyte*)ifile->line_buffer,
+ ifile->user_color_mode, (imbyte*)data);
+ else
+ iDoFillData(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (const imbyte*)ifile->line_buffer,
+ ifile->user_color_mode, (imbyte*)data);
+ break;
+ case IM_USHORT:
+ if (convert2bitmap)
+ iDoFillDataBitmap(ifile->width, ifile->height, line, plane, ifile->file_data_type,
+ ifile->file_color_mode, (const imushort*)ifile->line_buffer,
+ ifile->user_color_mode, (imbyte*)data);
+ else
+ iDoFillData(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (const imushort*)ifile->line_buffer,
+ ifile->user_color_mode, (imushort*)data);
+ break;
+ case IM_INT:
+ if (convert2bitmap)
+ iDoFillDataBitmap(ifile->width, ifile->height, line, plane, ifile->file_data_type,
+ ifile->file_color_mode, (const int*)ifile->line_buffer,
+ ifile->user_color_mode, (imbyte*)data);
+ else
+ iDoFillData(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (const int*)ifile->line_buffer,
+ ifile->user_color_mode, (int*)data);
+ break;
+ case IM_FLOAT:
+ if (convert2bitmap)
+ iDoFillDataBitmap(ifile->width, ifile->height, line, plane, ifile->file_data_type,
+ ifile->file_color_mode, (const float*)ifile->line_buffer,
+ ifile->user_color_mode, (imbyte*)data);
+ else
+ iDoFillData(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (const float*)ifile->line_buffer,
+ ifile->user_color_mode, (float*)data);
+ break;
+ case IM_CFLOAT:
+ if (convert2bitmap)
+ iDoFillDataBitmap(ifile->width, ifile->height, line, plane, ifile->file_data_type,
+ ifile->file_color_mode, (const double*)ifile->line_buffer,
+ ifile->user_color_mode, (imbyte*)data);
+ else
+ iDoFillData(ifile->width, ifile->height, line, plane,
+ ifile->file_color_mode, (const imcfloat*)ifile->line_buffer,
+ ifile->user_color_mode, (imcfloat*)data);
+ break;
+ }
+ }
+}
+
+void imFileLineBufferInit(imFile* ifile)
+{
+ ifile->line_buffer_size = imImageLineSize(ifile->width, ifile->file_color_mode, ifile->file_data_type);
+
+ if (ifile->switch_type && (ifile->file_data_type == IM_FLOAT || ifile->file_data_type == IM_CFLOAT))
+ ifile->line_buffer_extra += ifile->line_buffer_size; // double the size at least
+
+ if (ifile->line_buffer_size + ifile->line_buffer_extra > ifile->line_buffer_alloc)
+ {
+ ifile->line_buffer_alloc = ifile->line_buffer_size + ifile->line_buffer_extra;
+ ifile->line_buffer = realloc(ifile->line_buffer, ifile->line_buffer_alloc);
+ }
+}
+
+int imFileLineBufferCount(imFile* ifile)
+{
+ int count = ifile->height;
+ if (!imColorModeIsPacked(ifile->file_color_mode))
+ {
+ if (imColorModeHasAlpha(ifile->file_color_mode) && imColorModeHasAlpha(ifile->user_color_mode))
+ count *= imColorModeDepth(ifile->file_color_mode);
+ else
+ count *= imColorModeDepth(imColorModeSpace(ifile->file_color_mode));
+ }
+ return count;
+}
+
+void imFileLineBufferInc(imFile* ifile, int *row, int *plane)
+{
+ if (!imColorModeIsPacked(ifile->file_color_mode))
+ {
+ if (*row == ifile->height-1)
+ {
+ *row = 0;
+ (*plane)++;
+ return;
+ }
+ }
+
+ (*row)++;
+}
+
+int imFileCheckConversion(imFile* ifile)
+{
+ if ((ifile->file_color_mode & 0x3FF) == (ifile->user_color_mode & 0x3FF) && // compare only packing, alpha and color space
+ ifile->file_data_type == ifile->user_data_type)
+ return 1;
+
+ int user_color_space = imColorModeSpace(ifile->user_color_mode);
+ int file_color_space = imColorModeSpace(ifile->file_color_mode);
+
+ // NO color space conversion if file is not packed.
+ if(user_color_space != file_color_space &&
+ imColorModeDepth(file_color_space) > 1 &&
+ !imColorModeIsPacked(ifile->file_color_mode))
+ return 0;
+
+ if (ifile->is_new)
+ {
+ // (writing) from data to file
+
+ // NO data type conversions when writing.
+ if (ifile->file_data_type != ifile->user_data_type)
+ return 0;
+
+ // NO color space conversions when writing.
+ // If there is a necessary conversion the format driver will do it.
+ if (user_color_space != file_color_space)
+ return 0;
+ }
+ else
+ {
+ // (reading) from file to data
+
+ // Data type conversions only to byte
+ if (ifile->file_data_type != ifile->user_data_type &&
+ ifile->user_data_type != IM_BYTE)
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/im/src/im_fileraw.cpp b/im/src/im_fileraw.cpp
new file mode 100755
index 0000000..91be826
--- /dev/null
+++ b/im/src/im_fileraw.cpp
@@ -0,0 +1,66 @@
+/** \file
+ * \brief RAW File Format Open/New Functions
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_fileraw.cpp,v 1.3 2009/09/10 17:33:35 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+#include "im_counter.h"
+#include "im_raw.h"
+#include "im_format.h"
+#include "im_format_raw.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+
+imFile* imFileOpenRaw(const char* file_name, int *error)
+{
+ assert(file_name);
+
+ imFormat* iformat = imFormatInitRAW();
+ imFileFormatBase* ifileformat = iformat->Create();
+ *error = ifileformat->Open(file_name);
+ if (*error)
+ {
+ delete ifileformat;
+ return NULL;
+ }
+
+ imFileClear(ifileformat);
+
+ ifileformat->attrib_table = new imAttribTable(599);
+
+ ifileformat->counter = imCounterBegin(file_name);
+
+ return ifileformat;
+}
+
+imFile* imFileNewRaw(const char* file_name, int *error)
+{
+ assert(file_name);
+
+ imFormat* iformat = imFormatInitRAW();
+ imFileFormatBase* ifileformat = iformat->Create();
+ *error = ifileformat->New(file_name);
+ if (*error)
+ {
+ delete ifileformat;
+ return NULL;
+ }
+
+ imFileClear(ifileformat);
+
+ ifileformat->is_new = 1;
+ ifileformat->image_count = 0;
+ ifileformat->compression[0] = 0;
+
+ ifileformat->attrib_table = new imAttribTable(101);
+
+ ifileformat->counter = imCounterBegin(file_name);
+
+ return ifileformat;
+}
diff --git a/im/src/im_format.cpp b/im/src/im_format.cpp
new file mode 100755
index 0000000..d389743
--- /dev/null
+++ b/im/src/im_format.cpp
@@ -0,0 +1,299 @@
+/** \file
+ * \brief File Format Access
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $
+ */
+
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <memory.h>
+#include <string.h>
+#include <assert.h>
+
+#include "im.h"
+#include "im_format.h"
+#include "im_util.h"
+
+
+static imFormat* iFormatList[50];
+static int iFormatCount = 0;
+static int iFormatRegistredAll = 0;
+
+void imFormatRemoveAll(void)
+{
+ for (int i = 0; i < iFormatCount; i++)
+ {
+ imFormat* iformat = iFormatList[i];
+ delete iformat;
+ iFormatList[i] = NULL;
+ }
+ iFormatCount = 0;
+ iFormatRegistredAll = 0;
+}
+
+void imFormatRegister(imFormat* iformat)
+{
+ iFormatList[iFormatCount] = iformat;
+ iFormatCount++;
+}
+
+static imFormat* iFormatFind(const char* format)
+{
+ assert(format);
+
+ if (!iFormatRegistredAll)
+ {
+ imFormatRegisterInternal();
+ iFormatRegistredAll = 1;
+ }
+
+ for (int i = 0; i < iFormatCount; i++)
+ {
+ imFormat* iformat = iFormatList[i];
+ if (imStrEqual(format, iformat->format))
+ return iformat;
+ }
+ return NULL;
+}
+
+void imFormatList(char** format_list, int *format_count)
+{
+ assert(format_list);
+ assert(format_count);
+
+ if (!iFormatRegistredAll)
+ {
+ imFormatRegisterInternal();
+ iFormatRegistredAll = 1;
+ }
+
+ static char format_list_buffer[50][50];
+
+ *format_count = iFormatCount;
+ for (int i = 0; i < iFormatCount; i++)
+ {
+ imFormat* iformat = iFormatList[i];
+ strcpy(format_list_buffer[i], iformat->format);
+ format_list[i] = format_list_buffer[i];
+ }
+}
+
+int imFormatInfo(const char* format, char* desc, char* ext, int *can_sequence)
+{
+ imFormat* iformat = iFormatFind(format);
+ if (!iformat) return IM_ERR_FORMAT;
+
+ if (desc) strcpy(desc, iformat->desc);
+ if (ext) strcpy(ext, iformat->ext);
+ if (can_sequence) *can_sequence = iformat->can_sequence;
+
+ return IM_ERR_NONE;
+}
+
+int imFormatCompressions(const char* format, char** comp, int *comp_count, int color_mode, int data_type)
+{
+ imFormat* iformat = iFormatFind(format);
+ if (!iformat) return IM_ERR_FORMAT;
+
+ int count = 0;
+
+ static char comp_buffer[50][50];
+
+ for (int i = 0; i < iformat->comp_count; i++)
+ {
+ if (color_mode == -1 || data_type == -1 ||
+ iformat->CanWrite(iformat->comp[i], color_mode, data_type) == IM_ERR_NONE)
+ {
+ strcpy(comp_buffer[count], iformat->comp[i]);
+ comp[count] = comp_buffer[count];
+ count++;
+ }
+ }
+
+ *comp_count = count;
+
+ return IM_ERR_NONE;
+}
+
+int imFormatCanWriteImage(const char* format, const char* compression, int color_mode, int data_type)
+{
+ assert(format);
+
+ imFormat* iformat = iFormatFind(format);
+ if (!iformat) return IM_ERR_FORMAT;
+
+ int error = iformat->CanWrite(compression, color_mode, data_type);
+ return error;
+}
+
+static char* utlFileGetExt(const char *file_name)
+{
+ int len = strlen(file_name);
+
+ // Starts at the last character
+ int offset = len - 1;
+ while (offset != 0)
+ {
+ // if found a path separator, no extension found
+ if (file_name[offset] == '\\' || file_name[offset] == '/')
+ return NULL;
+
+ if (file_name[offset] == '.')
+ {
+ offset++;
+ break;
+ }
+
+ offset--;
+ }
+
+ // if at the first character, no extension found
+ if (offset == 0)
+ return NULL;
+
+ int ext_size = len - offset + 1;
+ char* file_ext = (char*)malloc(ext_size);
+
+ for (int i = 0; i < ext_size-1; i++)
+ file_ext[i] = (char)tolower(file_name[i+offset]);
+ file_ext[ext_size-1] = 0;
+
+ return file_ext;
+}
+
+imFileFormatBase* imFileFormatBaseOpen(const char* file_name, int *error)
+{
+ int i;
+
+ assert(file_name);
+ assert(error);
+
+ if (!iFormatRegistredAll)
+ {
+ imFormatRegisterInternal();
+ iFormatRegistredAll = 1;
+ }
+
+ int* ext_mark = new int [iFormatCount];
+ memset(ext_mark, 0, sizeof(int)*iFormatCount);
+
+ // Search for the extension first, this usually is going to speed the search
+ char* extension = utlFileGetExt(file_name);
+ if (extension)
+ {
+ for(i = 0; i < iFormatCount; i++)
+ {
+ imFormat* iformat = iFormatList[i];
+
+ if (strstr(iformat->ext, extension) != NULL)
+ {
+ ext_mark[i] = 1; // Mark this format to avoid testing it again in the next phase
+
+ imFileFormatBase* ifileformat = iformat->Create();
+ *error = ifileformat->Open(file_name);
+ if (*error != IM_ERR_NONE && *error != IM_ERR_FORMAT) // Error situation that must abort
+ { // Only IM_ERR_FORMAT is a valid error here
+ free(extension);
+ delete [] ext_mark;
+ delete ifileformat;
+ return NULL;
+ }
+ else if (*error == IM_ERR_NONE) // Sucessfully oppened the file
+ {
+ free(extension);
+ delete [] ext_mark;
+ return ifileformat;
+ }
+ }
+ }
+
+ free(extension);
+ }
+
+ // If the search did not work, try all the formats
+ // except those already tested.
+
+ for(i = 0; i < iFormatCount; i++)
+ {
+ if (!ext_mark[i])
+ {
+ imFormat* iformat = iFormatList[i];
+ imFileFormatBase* ifileformat = iformat->Create();
+ *error = ifileformat->Open(file_name);
+ if (*error != IM_ERR_NONE && *error != IM_ERR_FORMAT) // Error situation that must abort
+ { // Only IM_ERR_FORMAT is a valid error here
+ delete [] ext_mark;
+ delete ifileformat;
+ return NULL;
+ }
+ else if (*error == IM_ERR_NONE) // Sucessfully oppened the file
+ {
+ delete [] ext_mark;
+ return ifileformat;
+ }
+ }
+ }
+
+ *error = IM_ERR_FORMAT;
+ delete [] ext_mark;
+ return NULL;
+}
+
+imFileFormatBase* imFileFormatBaseOpenAs(const char* file_name, const char* format, int *error)
+{
+ assert(file_name);
+ assert(format);
+ assert(error);
+
+ if (!iFormatRegistredAll)
+ {
+ imFormatRegisterInternal();
+ iFormatRegistredAll = 1;
+ }
+
+ imFormat* iformat = iFormatFind(format);
+ if (!format)
+ {
+ *error = IM_ERR_FORMAT;
+ return NULL;
+ }
+
+ imFileFormatBase* ifileformat = iformat->Create();
+ *error = ifileformat->Open(file_name);
+ if (*error != IM_ERR_NONE && *error != IM_ERR_FORMAT) // Error situation that must abort
+ {
+ delete ifileformat;
+ return NULL;
+ }
+ else if (*error == IM_ERR_NONE) // Sucessfully oppened the file
+ return ifileformat;
+
+ *error = IM_ERR_FORMAT;
+ return NULL;
+}
+
+imFileFormatBase* imFileFormatBaseNew(const char* file_name, const char* format, int *error)
+{
+ assert(file_name);
+ assert(format);
+ assert(error);
+
+ imFormat* iformat = iFormatFind(format);
+ if (!iformat)
+ {
+ *error = IM_ERR_FORMAT;
+ return NULL;
+ }
+
+ imFileFormatBase* ifileformat = iformat->Create();
+ *error = ifileformat->New(file_name);
+ if (*error)
+ {
+ delete ifileformat;
+ return NULL;
+ }
+
+ return ifileformat;
+}
diff --git a/im/src/im_format_all.cpp b/im/src/im_format_all.cpp
new file mode 100755
index 0000000..c10b30a
--- /dev/null
+++ b/im/src/im_format_all.cpp
@@ -0,0 +1,34 @@
+/** \file
+ * \brief Register all the internal File Format Classes
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_all.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <assert.h>
+
+#include "im.h"
+#include "im_format.h"
+#include "im_format_all.h"
+
+void imFormatRegisterInternal(void)
+{
+ // IMPORTANT: RAW format is not registered.
+
+ // The internal formats registration
+ imFormatRegisterGIF();
+ imFormatRegisterBMP();
+ imFormatRegisterRAS();
+ imFormatRegisterICO();
+ imFormatRegisterPNM();
+ imFormatRegisterKRN();
+ imFormatRegisterLED();
+ imFormatRegisterSGI();
+ imFormatRegisterPCX();
+ imFormatRegisterTGA();
+}
+
diff --git a/im/src/im_format_bmp.cpp b/im/src/im_format_bmp.cpp
new file mode 100755
index 0000000..5cfe013
--- /dev/null
+++ b/im/src/im_format_bmp.cpp
@@ -0,0 +1,949 @@
+/** \file
+ * \brief BMP - Windows Device Independent Bitmap
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_bmp.cpp,v 1.4 2009/10/01 14:15:47 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+
+#define BMP_ID 0x4d42 /* BMP "magic" number */
+
+#define BMP_COMPRESS_RGB 0L /* No compression */
+#define BMP_COMPRESS_RLE8 1L /* 8 bits per pixel compression */
+#define BMP_COMPRESS_RLE4 2L /* 4 bits per pixel compression */
+#define BMP_BITFIELDS 3L /* no compression, palette is mask for 16 and 32 bits images */
+
+/* State-machine definitions */
+#define BMP_READING 0 /* General READING mode */
+#define BMP_ENCODING 1 /* Encoding same-color pixel runs */
+#define BMP_ABSMODE 2 /* Absolute-mode encoding */
+#define BMP_SINGLE 3 /* Encoding short absolute-mode runs */
+#define BMP_ENDOFLINE 4 /* End of scan line detected */
+
+#define BMP_LSN(value) (unsigned char)((value) & 0x0f) /* Least-significant nibble */
+#define BMP_MSN(value) (unsigned char)(((value) & 0xf0) >> 4) /* Most-significant nibble */
+
+
+/* File Header Structure.
+ * 2 Type; File Type Identifier
+ * 4 FileSize; Size of File
+ * 2 Reserved1; Reserved (should be 0)
+ * 2 Reserved2; Reserved (should be 0)
+ * 4 Offset; Offset to bitmap data
+ * 14 TOTAL */
+
+/* Information Header Structure.
+ * 4 Size; Size of Remaining Header
+ * 4 Width; Width of Bitmap in Pixels
+ * 4 Height; Height of Bitmap in Pixels
+ * 2 Planes; Number of Planes
+ * 2 BitCount; Bits Per Pixel
+ * 4 Compression; Compression Scheme
+ * 4 SizeImage; Size of bitmap
+ * 4 XPelsPerMeter; Horz. Resolution in Pixels/Meter
+ * 4 YPelsPerMeter; Vert. Resolution in Pixels/Meter
+ * 4 ClrUsed; Number of Colors in Color Table
+ * 4 ClrImportant; Number of Important Colors
+ * 40 TOTAL V3
+ * 4 RedMask;
+ * 4 GreenMask;
+ * 4 BlueMask;
+ * 4 AlphaMask;
+ * 4 CSType;
+ * 12 ciexyzRed(x, y, z); [3*FXPT2DOT30]
+ * 12 ciexyzGreen(x, y, z); "
+ * 12 ciexyzBlue(x, y, z); "
+ * 4 GammaRed;
+ * 4 GammaGreen;
+ * 4 GammaBlue;
+ * 108 TOTAL V4 (not supported here)
+ * 4 Intent;
+ * 4 ProfileData;
+ * 4 ProfileSize;
+ * 4 Reserved;
+ * 120 TOTAL V5 (not supported here)
+ */
+
+/* RGB Color Quadruple Structure. */
+/* 1 rgbBlue; Blue Intensity Value */
+/* 1 rgbGreen; Green Intensity Value */
+/* 1 rgbRed; Red Intensity Value */
+/* 1 rgbReserved; Reserved (should be 0) */
+/* 4 */
+
+static int iBMPDecodeScanLine(imBinFile* handle, unsigned char* DecodedBuffer, int Width)
+{
+ unsigned char runCount; /* Number of pixels in the run */
+ unsigned char runValue; /* Value of pixels in the run */
+ int Index = 0; /* The index of DecodedBuffer */
+ int cont = 1, remain;
+
+ while (cont)
+ {
+ imBinFileRead(handle, &runCount, 1, 1); /* Number of pixels in the run */
+ imBinFileRead(handle, &runValue, 1, 1); /* Value of pixels in the run */
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (runCount)
+ {
+ while (runCount-- && Index < Width)
+ DecodedBuffer[Index++] = runValue;
+ }
+ else /* Abssolute Mode or Escape Code */
+ {
+ switch(runValue)
+ {
+ case 0: /* End of Scan Line Escape Code */
+ case 1: /* End of Bitmap Escape Code */
+ cont = 0;
+ break;
+ case 2: /* Delta Escape Code (ignored) */
+ imBinFileRead(handle, &runCount, 1, 1);
+ imBinFileRead(handle, &runCount, 1, 1);
+ break;
+ default: /* Abssolute Mode */
+ remain = runValue % 2;
+ runValue = (unsigned char)(Index + runValue < (Width + 1)? runValue: (Width - 1) - Index);
+ imBinFileRead(handle, DecodedBuffer + Index, runValue, 1);
+ if (remain)
+ imBinFileSeekOffset(handle, 1);
+ Index += runValue;
+ }
+ }
+
+ if (imBinFileError(handle) || Index > Width)
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+static int iBMPEncodeScanLine(unsigned char* EncodedBuffer, unsigned char* sl, int np)
+{
+ int slx = 0; /* Scan line index */
+ int state = BMP_READING; /* State machine control variable */
+ int count = 0; /* Used by various states */
+ unsigned char pixel; /* Holds single pixels from sl */
+ int done = 0; /* Ends while loop when true */
+ int oldcount, oldslx; /* Copies of count and slx */
+ int BufSize = 0;
+
+ while (!done)
+ {
+ switch (state)
+ {
+ case BMP_READING:
+ /* Input: */
+ /* np == number of pixels in scan line */
+ /* sl == scan line */
+ /* sl[slx] == next pixel to process */
+
+ if (slx >= np) /* No pixels left */
+ state = BMP_ENDOFLINE;
+ else if (slx == np - 1) /* One pixel left */
+ {
+ count = 1;
+ state = BMP_SINGLE;
+ }
+ else if (sl[slx] == sl[slx + 1]) /* Next 2 pixels equal */
+ state = BMP_ENCODING;
+ else /* Next 2 pixels differ */
+ state = BMP_ABSMODE;
+
+ break;
+ case BMP_ENCODING:
+ /* Input: */
+ /* slx <= np - 2 (at least 2 pixels in run) */
+ /* sl[slx] == first pixel of run */
+ /* sl[slx] == sl[slx + 1] */
+
+ count = 2;
+ pixel = sl[slx];
+ slx += 2;
+
+ while ((slx < np) && (pixel == sl[slx]) && (count < 255))
+ {
+ count++;
+ slx++;
+ }
+
+ *EncodedBuffer++ = (unsigned char)count;
+ BufSize++;
+ *EncodedBuffer++ = pixel;
+ BufSize++;
+ state = BMP_READING;
+
+ break;
+ case BMP_ABSMODE:
+ /* Input: */
+ /* slx <= np - 2 (at least 2 pixels in run) */
+ /* sl[slx] == first pixel of run */
+ /* sl[slx] != sl[slx + 1] */
+
+ oldslx = slx;
+ count = 2;
+ slx += 2;
+
+ /* Compute number of bytes in run */
+ while ((slx < np) && (sl[slx] != sl[slx - 1]) && (count < 255))
+ {
+ count++;
+ slx++;
+ }
+
+ /* If same-color run found, back up one byte */
+ if ((slx < np) && (sl[slx] == sl[slx - 1]))
+ if (count > 1)
+ count--;
+
+ slx = oldslx; /* Restore scan-line index */
+
+ /* Output short absolute runs of less than 3 pixels */
+ if (count < 3 )
+ state = BMP_SINGLE;
+ else
+ {
+ /* Output absolute-mode run */
+ *EncodedBuffer++ = 0;
+ BufSize++;
+ *EncodedBuffer++ = (unsigned char)count;
+ BufSize++;
+ oldcount = count;
+
+ while (count > 0)
+ {
+ *EncodedBuffer++ = sl[slx];
+ BufSize++;
+ slx++;
+ count--;
+ }
+
+ if (oldcount % 2)
+ {
+ *EncodedBuffer++ = 0;
+ BufSize++;
+ }
+
+ state = BMP_READING;
+ }
+ break;
+
+ case BMP_SINGLE:
+ /* Input: */
+ /* count == number of pixels to output */
+ /* slx < np */
+ /* sl[slx] == first pixel of run */
+ /* sl[slx] != sl[slx + 1] */
+
+ while (count > 0)
+ {
+ *EncodedBuffer++ = (unsigned char)1;
+ BufSize++;
+ *EncodedBuffer++ = sl[slx];
+ BufSize++;
+ slx++;
+ count--;
+ }
+
+ state = BMP_READING;
+
+ break;
+ case BMP_ENDOFLINE:
+ *EncodedBuffer++ = (unsigned char)0;
+ BufSize++;
+ *EncodedBuffer++ = (unsigned char)0;
+ BufSize++;
+ done = 1;
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ return BufSize;
+}
+
+static const char* iBMPCompTable[2] =
+{
+ "NONE",
+ "RLE"
+};
+
+class imFileFormatBMP: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ unsigned short bpp; /* number of bits per pixel */
+ unsigned int offset, /* image data offset, used only when reading */
+ comp_type; /* bmp compression information */
+ int is_os2, /* indicates an os2 1.x BMP */
+ line_raw_size; // raw line size
+ unsigned int rmask, gmask, bmask,
+ roff, goff, boff; /* pixel bit mask control when reading 16 and 32 bpp images */
+
+ int ReadPalette();
+ int WritePalette();
+ void FixRGBOrder();
+
+public:
+ imFileFormatBMP(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatBMP() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatBMP: public imFormat
+{
+public:
+ imFormatBMP()
+ :imFormat("BMP",
+ "Windows Device Independent Bitmap",
+ "*.bmp;*.dib;",
+ iBMPCompTable,
+ 2,
+ 0)
+ {}
+ ~imFormatBMP() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatBMP(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+
+void imFormatRegisterBMP(void)
+{
+ imFormatRegister(new imFormatBMP());
+}
+
+int imFileFormatBMP::Open(const char* file_name)
+{
+ unsigned short id;
+ unsigned int dword;
+
+ /* opens the binary file for reading with intel byte order */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ /* reads the BMP format identifier */
+ imBinFileRead(handle, &id, 1, 2);
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (id != BMP_ID)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ /* jump 8 bytes (file size,reserved) */
+ imBinFileSeekOffset(handle, 8);
+
+ /* reads the image offset */
+ imBinFileRead(handle, &this->offset, 1, 4);
+
+ /* reads the header size */
+ imBinFileRead(handle, &dword, 1, 4);
+
+ if (dword == 40)
+ this->is_os2 = 0;
+ else if (dword == 12)
+ this->is_os2 = 1;
+ else
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ this->image_count = 1;
+
+ /* reads the compression information */
+ if (this->is_os2)
+ {
+ this->comp_type = BMP_COMPRESS_RGB;
+ strcpy(this->compression, "NONE");
+ }
+ else
+ {
+ imBinFileSeekOffset(handle, 12);
+
+ imBinFileRead(handle, &this->comp_type, 1, 4);
+
+ switch (this->comp_type)
+ {
+ case BMP_COMPRESS_RGB:
+ strcpy(this->compression, "NONE");
+ break;
+ case BMP_COMPRESS_RLE8:
+ strcpy(this->compression, "RLE");
+ break;
+ case BMP_COMPRESS_RLE4:
+ default:
+ imBinFileClose(handle);
+ return IM_ERR_COMPRESS;
+ }
+
+ imBinFileSeekOffset(handle, -16);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatBMP::New(const char* file_name)
+{
+ /* opens the binary file for writing with intel byte order */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatBMP::Close()
+{
+ imBinFileClose(handle);
+}
+
+void* imFileFormatBMP::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatBMP::ReadImageInfo(int index)
+{
+ (void)index;
+ unsigned int dword;
+
+ this->file_data_type = IM_BYTE;
+
+ if (this->is_os2)
+ {
+ short word;
+
+ /* reads the image width */
+ imBinFileRead(handle, &word, 1, 2);
+ this->width = (int)word;
+
+ /* reads the image height */
+ imBinFileRead(handle, &word, 1, 2);
+ this->height = (int)((word < 0)? -word: word);
+
+ dword = word; // it will be used later
+ }
+ else
+ {
+ /* reads the image width */
+ imBinFileRead(handle, &dword, 1, 4);
+ this->width = (int)dword;
+
+ /* reads the image height */
+ imBinFileRead(handle, &dword, 1, 4);
+ this->height = (int)dword;
+ if (this->height < 0)
+ this->height = -this->height;
+ }
+
+ /* jump 2 bytes (planes) */
+ imBinFileSeekOffset(handle, 2);
+
+ /* reads the number of bits per pixel */
+ imBinFileRead(handle, &this->bpp, 1, 2);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ // sanity check
+ if (this->bpp != 1 && this->bpp != 4 && this->bpp != 8 &&
+ this->bpp != 16 && this->bpp != 24 && this->bpp != 32)
+ return IM_ERR_DATA;
+
+ // another sanity check
+ if (this->comp_type == BMP_BITFIELDS && this->bpp != 16 && this->bpp != 32)
+ return IM_ERR_DATA;
+
+ if (this->bpp > 8)
+ {
+ this->file_color_mode = IM_RGB;
+ this->file_color_mode |= IM_PACKED;
+ }
+ else
+ {
+ this->palette_count = 1 << bpp;
+ this->file_color_mode = IM_MAP;
+ }
+
+ if (this->bpp < 8)
+ this->convert_bpp = this->bpp;
+
+ if (this->bpp == 32)
+ this->file_color_mode |= IM_ALPHA;
+
+ if (dword < 0)
+ this->file_color_mode |= IM_TOPDOWN;
+
+ this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 4);
+ this->line_buffer_extra = 4; // room enough for padding
+
+ if (this->is_os2)
+ {
+ if (this->bpp < 24)
+ return ReadPalette();
+
+ return IM_ERR_NONE;
+ }
+
+ /* we already read the compression information */
+ /* jump 8 bytes (compression, image size) */
+ imBinFileSeekOffset(handle, 8);
+
+ /* read the x resolution */
+ imBinFileRead(handle, &dword, 1, 4);
+ float xres = (float)dword / 100.0f;
+
+ /* read the y resolution */
+ imBinFileRead(handle, &dword, 1, 4);
+ float yres = (float)dword / 100.0f;
+
+ if (xres && yres)
+ {
+ imAttribTable* attrib_table = AttribTable();
+ attrib_table->Set("XResolution", IM_FLOAT, 1, &xres);
+ attrib_table->Set("YResolution", IM_FLOAT, 1, &yres);
+ attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPC");
+ }
+
+ if (this->bpp <= 8)
+ {
+ /* reads the number of colors used */
+ imBinFileRead(handle, &dword, 1, 4);
+
+ /* updates the palette_count based on the number of colors used */
+ if (dword != 0 && dword < (unsigned int)this->palette_count)
+ this->palette_count = dword;
+
+ /* jump 4 bytes (important colors) */
+ imBinFileSeekOffset(handle, 4);
+ }
+ else
+ {
+ /* jump 8 bytes (used colors, important colors) */
+ imBinFileSeekOffset(handle, 8);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->bpp <= 8)
+ return ReadPalette();
+
+ if (this->bpp == 16 || this->bpp == 32)
+ {
+ if (this->comp_type == BMP_BITFIELDS)
+ {
+ unsigned int Mask;
+ unsigned int PalMask[3];
+
+ imBinFileRead(handle, PalMask, 3, 4);
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ this->roff = 0;
+ this->rmask = Mask = PalMask[0];
+ while (!(Mask & 0x01) && (Mask != 0))
+ {Mask >>= 1; this->roff++;}
+
+ this->goff = 0;
+ this->gmask = Mask = PalMask[1];
+ while (!(Mask & 0x01) && (Mask != 0))
+ {Mask >>= 1; this->goff++;}
+
+ this->boff = 0;
+ this->bmask = Mask = PalMask[2];
+ while (!(Mask & 0x01) && (Mask != 0))
+ {Mask >>= 1; this->boff++;}
+ }
+ else
+ {
+ if (this->bpp == 16)
+ {
+ this->rmask = 0x7C00;
+ this->roff = 10;
+
+ this->gmask = 0x03E0;
+ this->goff = 5;
+
+ this->bmask = 0x001F;
+ this->boff = 0;
+ }
+ else
+ {
+ this->rmask = 0x00FF0000;
+ this->roff = 16;
+
+ this->gmask = 0x0000FF00;
+ this->goff = 8;
+
+ this->bmask = 0x000000FF;
+ this->boff = 0;
+ }
+ }
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatBMP::WriteImageInfo()
+{
+ // force bottom up orientation
+ this->file_data_type = IM_BYTE;
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+
+ if (imStrEqual(this->compression, "RLE"))
+ this->comp_type = BMP_COMPRESS_RLE8;
+ else
+ this->comp_type = BMP_COMPRESS_RGB;
+
+ if (this->file_color_mode == IM_BINARY)
+ {
+ this->bpp = 1;
+ this->convert_bpp = 1;
+ }
+ else if (this->file_color_mode == IM_RGB)
+ {
+ this->file_color_mode |= IM_PACKED;
+ this->bpp = 24;
+
+ if (imColorModeHasAlpha(this->user_color_mode))
+ {
+ this->file_color_mode |= IM_ALPHA;
+ this->bpp = 32;
+
+ this->rmask = 0x00FF0000;
+ this->roff = 16;
+
+ this->gmask = 0x0000FF00;
+ this->goff = 8;
+
+ this->bmask = 0x000000FF;
+ this->boff = 0;
+ }
+ }
+ else
+ this->bpp = 8;
+
+ this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 4);
+ this->line_buffer_extra = 4; // room enough for padding
+
+ if (this->comp_type == BMP_COMPRESS_RLE8)
+ {
+ // allocates more than enough since compression algoritm can be ineficient
+ this->line_buffer_extra += 2*this->line_raw_size;
+ }
+
+ /* writes the BMP file header */
+ int palette_size = (this->bpp > 8)? 0: palette_count*4;
+ short word_value = BMP_ID;
+ imBinFileWrite(handle, &word_value, 1, 2); /* identifier */
+ unsigned int dword_value = 14 + 40 + palette_size + line_raw_size * this->height;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* file size for uncompressed images */
+ word_value = 0;
+ imBinFileWrite(handle, &word_value, 1, 2); /* reserved 1 */
+ imBinFileWrite(handle, &word_value, 1, 2); /* reserved 2 */
+ dword_value = 14 + 40 + palette_size;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* data offset */
+
+ /* writes the BMP info header */
+
+ dword_value = 40;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* header size */
+ dword_value = this->width;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* width */
+ dword_value = this->height;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* height */
+ word_value = 1;
+ imBinFileWrite(handle, &word_value, 1, 2); /* planes */
+ word_value = this->bpp;
+ imBinFileWrite(handle, &word_value, 1, 2); /* bpp */
+ dword_value = this->comp_type;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* compression */
+ dword_value = line_raw_size * this->height;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* image size */
+
+ imAttribTable* attrib_table = AttribTable();
+ unsigned int xppm = 0, yppm = 0;
+
+ const void* attrib_data = attrib_table->Get("ResolutionUnit");
+ if (attrib_data)
+ {
+ char* res_unit = (char*)attrib_data;
+
+ float* xres = (float*)attrib_table->Get("XResolution");
+ float* yres = (float*)attrib_table->Get("YResolution");
+
+ if (xres && yres)
+ {
+ if (imStrEqual(res_unit, "DPI"))
+ {
+ xppm = (unsigned int)(*xres * 100. / 2.54);
+ yppm = (unsigned int)(*yres * 100. / 2.54);
+ }
+ else
+ {
+ xppm = (unsigned int)(*xres * 100.);
+ yppm = (unsigned int)(*yres * 100.);
+ }
+ }
+ }
+
+ imBinFileWrite(handle, &xppm, 1, 4); /* x dpm */
+ imBinFileWrite(handle, &yppm, 1, 4); /* y dpm */
+
+ dword_value = (this->bpp > 8)? 0: this->palette_count;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* colors used */
+ dword_value = 0;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* colors important (all) */
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->bpp < 24)
+ return WritePalette();
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatBMP::ReadPalette()
+{
+ int nc;
+ if (this->is_os2)
+ nc = 3;
+ else
+ nc = 4;
+
+ /* reads the color palette */
+ unsigned char bmp_colors[256 * 4];
+ imBinFileRead(handle, bmp_colors, this->palette_count * nc, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * nc;
+ this->palette[c] = imColorEncode(bmp_colors[i + 2],
+ bmp_colors[i + 1],
+ bmp_colors[i]);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatBMP::WritePalette()
+{
+ unsigned char bmp_colors[256 * 4];
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * 4;
+ imColorDecode(&bmp_colors[i + 2], &bmp_colors[i + 1], &bmp_colors[i], this->palette[c]);
+ bmp_colors[i + 3] = 0;
+ }
+
+ /* writes the color palette */
+ imBinFileWrite(handle, bmp_colors, this->palette_count * 4, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatBMP::FixRGBOrder()
+{
+ int x;
+
+ switch (this->bpp)
+ {
+ case 16:
+ {
+ /* inverts the WORD values if not intel */
+ if (imBinCPUByteOrder() == IM_BIGENDIAN)
+ imBinSwapBytes2(this->line_buffer, this->width);
+
+ imushort* word_data = (imushort*)this->line_buffer;
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+
+ // from end to start
+ for (x = this->width-1; x >= 0; x--)
+ {
+ imushort word_value = word_data[x];
+ int c = x*3;
+ byte_data[c] = (imbyte)((((this->rmask & word_value) >> this->roff) * 255) / (this->rmask >> this->roff));
+ byte_data[c+1] = (imbyte)((((this->gmask & word_value) >> this->goff) * 255) / (this->gmask >> this->goff));
+ byte_data[c+2] = (imbyte)((((this->bmask & word_value) >> this->boff) * 255) / (this->bmask >> this->boff));
+ }
+ }
+ break;
+ case 32:
+ {
+ /* inverts the DWORD values if not intel */
+ if (imBinCPUByteOrder() == IM_BIGENDIAN)
+ imBinSwapBytes4(this->line_buffer, this->width);
+
+ unsigned int* dword_data = (unsigned int*)this->line_buffer;
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+
+ for (x = 0; x < this->width; x++)
+ {
+ unsigned int dword_value = dword_data[x];
+ int c = x*4;
+ byte_data[c] = (imbyte)((this->rmask & dword_value) >> this->roff);
+ byte_data[c+1] = (imbyte)((this->gmask & dword_value) >> this->goff);
+ byte_data[c+2] = (imbyte)((this->bmask & dword_value) >> this->boff);
+ byte_data[c+3] = (imbyte)((0xFF000000 & dword_value) >> 24);
+ }
+ }
+ break;
+ default: // 24
+ {
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+ for (x = 0; x < this->width; x++)
+ {
+ int c = x*3;
+ imbyte temp = byte_data[c]; // swap R and B
+ byte_data[c] = byte_data[c+2];
+ byte_data[c+2] = temp;
+ }
+ }
+ break;
+ }
+}
+
+int imFileFormatBMP::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading BMP...");
+
+ /* jump to the begin of image data */
+ imBinFileSeekTo(handle, this->offset);
+
+ for (int row = 0; row < this->height; row++)
+ {
+ /* read and decompress the data */
+ if (this->comp_type == BMP_COMPRESS_RGB)
+ {
+ imBinFileRead(handle, this->line_buffer, this->line_raw_size, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ if (iBMPDecodeScanLine(handle, (imbyte*)this->line_buffer, this->width) == IM_ERR_ACCESS)
+ return IM_ERR_ACCESS;
+ }
+
+ if (this->bpp > 8)
+ FixRGBOrder();
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatBMP::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing BMP...");
+
+ imbyte* compressed_buffer = NULL;
+ if (this->comp_type == BMP_COMPRESS_RLE8) // point to the extra buffer
+ compressed_buffer = (imbyte*)this->line_buffer + this->line_buffer_size+4;
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ if (this->bpp > 8)
+ FixRGBOrder();
+
+ if (this->comp_type == BMP_COMPRESS_RGB)
+ {
+ imBinFileWrite(handle, this->line_buffer, this->line_raw_size, 1);
+ }
+ else
+ {
+ int compressed_size = iBMPEncodeScanLine(compressed_buffer, (imbyte*)this->line_buffer, this->width);
+ imBinFileWrite(handle, compressed_buffer, compressed_size, 1);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFormatBMP::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE") && !imStrEqual(compression, "RLE"))
+ return IM_ERR_COMPRESS;
+
+ if (imStrEqual(compression, "RLE") && (color_space == IM_RGB || color_space == IM_BINARY))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_ecw.cpp b/im/src/im_format_ecw.cpp
new file mode 100755
index 0000000..bba99b0
--- /dev/null
+++ b/im/src/im_format_ecw.cpp
@@ -0,0 +1,385 @@
+/** \file
+ * \brief ECW - ECW JPEG 2000
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#include "im_format.h"
+#include "im_util.h"
+#include "im_format_ecw.h"
+#include "im_counter.h"
+
+#include <NCSECWClient.h>
+// #include <NCSEcwCompressClient.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+static const char* iECWCompTable[2] =
+{
+ "ECW",
+ "JPEG-2000",
+};
+
+class imFileFormatECW: public imFileFormatBase
+{
+ NCSFileView *pNCSFileView;
+// NCSEcwCompressClient *pClient;
+
+public:
+ imFileFormatECW(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatECW() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo(){return 0;} // do nothing for now;
+ int WriteImageData(void* data){(void)data; return 0;} // do nothing for now;
+};
+
+class imFormatECW: public imFormat
+{
+public:
+ imFormatECW()
+ :imFormat("ECW",
+ "ECW JPEG-2000 File Format",
+ "*.ecw;*.jp2;*.j2k;*.jpc;*.j2c;",
+ iECWCompTable,
+ 2,
+ 0)
+ {}
+ ~imFormatECW() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatECW(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+void imFormatRegisterECW(void)
+{
+ imFormatRegister(new imFormatECW());
+}
+
+int imFileFormatECW::Open(const char* file_name)
+{
+ NCSError eError = NCScbmOpenFileView((char*)file_name, &this->pNCSFileView, NULL);
+ if (eError != NCS_SUCCESS)
+ {
+ if (eError == NCS_FILE_OPEN_ERROR ||
+ eError == NCS_FILE_NOT_FOUND ||
+ eError == NCS_FILE_INVALID)
+ return IM_ERR_OPEN;
+ else if (eError == NCS_FILE_OPEN_FAILED)
+ return IM_ERR_FORMAT;
+ else
+ return IM_ERR_ACCESS;
+ }
+
+ NCSFileType fileType = NCScbmGetFileType(this->pNCSFileView);
+ if (fileType == NCS_FILE_ECW)
+ strcpy(this->compression, "ECW");
+ else if (fileType == NCS_FILE_JP2)
+ strcpy(this->compression, "JPEG-2000");
+ else
+ return IM_ERR_COMPRESS;
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatECW::New(const char* file_name)
+{
+ strcpy(this->compression, "JPEG-2000");
+ this->image_count = 1;
+
+ (void)file_name;
+ return IM_ERR_FORMAT;
+}
+
+void imFileFormatECW::Close()
+{
+ if (this->is_new)
+ ;// NCSEcwCompressClose(this->pClient);
+ else
+ NCScbmCloseFileView(this->pNCSFileView);
+}
+
+void* imFileFormatECW::Handle(int index)
+{
+ (void)index;
+
+ if (this->is_new)
+ return NULL; // return (void*)this->pClient;
+ else
+ return (void*)this->pNCSFileView;
+}
+
+int imFileFormatECW::ReadImageInfo(int index)
+{
+ NCSFileViewFileInfoEx *pNCSFileInfo;
+ imAttribTable* attrib_table = AttribTable();
+ (void)index;
+
+ if (NCScbmGetViewFileInfoEx(this->pNCSFileView, &pNCSFileInfo) != NCS_SUCCESS)
+ return IM_ERR_ACCESS;
+
+ this->width = pNCSFileInfo->nSizeX;
+ this->height = pNCSFileInfo->nSizeY;
+
+ switch(pNCSFileInfo->eColorSpace)
+ {
+ case NCSCS_GREYSCALE:
+ this->file_color_mode = IM_GRAY;
+ break;
+ case NCSCS_YUV:
+ case NCSCS_sRGB:
+ this->file_color_mode = IM_RGB;
+ break;
+ case NCSCS_YCbCr:
+ this->file_color_mode = IM_YCBCR;
+ break;
+ case NCSCS_MULTIBAND:
+ /* multiband data, we read only one band */
+ this->file_color_mode = IM_GRAY;
+ attrib_table->Set("MultiBandCount", IM_USHORT, 1, (void*)&pNCSFileInfo->nBands);
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ switch(pNCSFileInfo->eCellType)
+ {
+ case NCSCT_INT8:
+ case NCSCT_UINT8:
+ this->file_data_type = IM_BYTE;
+ break;
+ case NCSCT_INT16:
+ case NCSCT_UINT16:
+ this->file_data_type = IM_USHORT;
+ break;
+ case NCSCT_UINT64:
+ case NCSCT_INT64:
+ case NCSCT_UINT32:
+ case NCSCT_INT32:
+ // Should be: this->file_data_type = IM_INT;
+ // but 32bits ints are not supported by the NCScbmReadViewLineBILEx function
+ this->file_data_type = IM_USHORT;
+ break;
+ case NCSCT_IEEE4:
+ case NCSCT_IEEE8:
+ this->file_data_type = IM_FLOAT;
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ int prec = pNCSFileInfo->pBands->nBits;
+ if (prec < 8)
+ this->convert_bpp = -prec; // just expand to 0-255
+
+ if (prec == 1 && this->file_color_mode == IM_GRAY)
+ this->file_color_mode = IM_BINARY;
+
+ if (pNCSFileInfo->nBands > imColorModeDepth(this->file_color_mode))
+ this->file_color_mode |= IM_ALPHA;
+
+ if (this->file_color_mode != IM_GRAY)
+ this->file_color_mode |= IM_PACKED;
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ float float_value = (float)pNCSFileInfo->fOriginX;
+ attrib_table->Set("OriginX", IM_FLOAT, 1, (void*)&float_value);
+
+ float_value = (float)pNCSFileInfo->fOriginY;
+ attrib_table->Set("OriginY", IM_FLOAT, 1, (void*)&float_value);
+
+ float_value = (float)pNCSFileInfo->fCWRotationDegrees;
+ attrib_table->Set("Rotation", IM_FLOAT, 1, (void*)&float_value);
+
+ float_value = (float)pNCSFileInfo->fCellIncrementX;
+ attrib_table->Set("CellIncrementX", IM_FLOAT, 1, (void*)&float_value);
+
+ float_value = (float)pNCSFileInfo->fCellIncrementY;
+ attrib_table->Set("CellIncrementY", IM_FLOAT, 1, (void*)&float_value);
+
+ attrib_table->Set("Datum", IM_BYTE, strlen(pNCSFileInfo->szDatum)+1, pNCSFileInfo->szDatum);
+ attrib_table->Set("Projection", IM_BYTE, strlen(pNCSFileInfo->szProjection)+1, pNCSFileInfo->szProjection);
+
+ switch (pNCSFileInfo->eCellSizeUnits)
+ {
+ case ECW_CELL_UNITS_INVALID:
+ attrib_table->Set("CellUnits", IM_BYTE, 8, "INVALID");
+ break;
+ case ECW_CELL_UNITS_METERS:
+ attrib_table->Set("CellUnits", IM_BYTE, 7, "METERS");
+ break;
+ case ECW_CELL_UNITS_DEGREES:
+ attrib_table->Set("CellUnits", IM_BYTE, 7, "DEGREES");
+ break;
+ case ECW_CELL_UNITS_FEET:
+ attrib_table->Set("CellUnits", IM_BYTE, 5, "FEET");
+ break;
+ case ECW_CELL_UNITS_UNKNOWN:
+ attrib_table->Set("CellUnits", IM_BYTE, 8, "UNKNOWN");
+ break;
+ }
+
+ float_value = (float)pNCSFileInfo->nCompressionRate;
+ attrib_table->Set("CompressionRatio", IM_FLOAT, 1, (void*)&float_value);
+
+ return IM_ERR_NONE;
+}
+
+static void iCopyDataBuffer(UINT8 **ppOutputLine, imbyte* line_buffer, int nBands, int view_width, int type_size)
+{
+ if (nBands > 1)
+ {
+ for(int i = 0; i < view_width; i++)
+ {
+ for(int j = 0; j < nBands; j++)
+ {
+ for(int k = 0; k < type_size; k++)
+ {
+ *line_buffer++ = (ppOutputLine[j])[i*type_size + k];
+ }
+ }
+ }
+ }
+ else
+ memcpy(line_buffer, ppOutputLine[0], nBands*type_size*view_width);
+}
+
+int imFileFormatECW::ReadImageData(void* data)
+{
+ imAttribTable* attrib_table = AttribTable();
+ int i, *attrib_data, view_width, view_height,
+ nBands = imColorModeDepth(this->file_color_mode);
+
+ // this size is free, can be anything, but we restricted to less than the image size
+ attrib_data = (int*)attrib_table->Get("ViewWidth");
+ view_width = attrib_data? *attrib_data: this->width;
+ if (view_width > this->width) view_width = this->width;
+
+ attrib_data = (int*)attrib_table->Get("ViewHeight");
+ view_height = attrib_data? *attrib_data: this->height;
+ if (view_height > this->height) view_height = this->height;
+
+ imCounterTotal(this->counter, view_height, "Reading ECW...");
+
+ {
+ int xmin, xmax, ymin, ymax, band_start;
+
+ // full image if not defined.
+ // this size must be inside the image
+ attrib_data = (int*)attrib_table->Get("ViewXmin");
+ xmin = attrib_data? *attrib_data: 0;
+ if (xmin < 0) xmin = 0;
+
+ attrib_data = (int*)attrib_table->Get("ViewYmin");
+ ymin = attrib_data? *attrib_data: 0;
+ if (ymin < 0) ymin = 0;
+
+ attrib_data = (int*)attrib_table->Get("ViewXmax");
+ xmax = attrib_data? *attrib_data: this->width-1;
+ if (xmax > this->width-1) xmax = this->width-1;
+
+ attrib_data = (int*)attrib_table->Get("ViewYmax");
+ ymax = attrib_data? *attrib_data: this->height-1;
+ if (ymax > this->height-1) ymax = this->height-1;
+
+ band_start = 0;
+ UINT16* start_plane = (UINT16*)attrib_table->Get("MultiBandSelect");
+ if (start_plane)
+ band_start = *start_plane;
+
+ UINT32 *pBandList = (UINT32*)malloc(sizeof(UINT32)*nBands);
+ for(i = 0; i < nBands; i++)
+ pBandList[i] = i+band_start;
+
+ NCSError eError = NCScbmSetFileView(this->pNCSFileView, nBands, pBandList,
+ xmin, ymin, xmax, ymax,
+ view_width, view_height);
+ free(pBandList);
+
+ if( eError != NCS_SUCCESS)
+ return IM_ERR_DATA;
+ }
+
+ // this is necessary to fool line buffer management
+ this->width = view_width;
+ this->height = view_height;
+ this->line_buffer_size = imImageLineSize(this->width, this->file_color_mode, this->file_data_type);
+
+ NCSEcwCellType eType = NCSCT_UINT8;
+ int type_size = 1;
+ if (this->file_data_type == IM_USHORT)
+ {
+ eType = NCSCT_UINT16;
+ type_size = 2;
+ }
+ else if (this->file_data_type == IM_FLOAT)
+ {
+ eType = NCSCT_IEEE4;
+ type_size = 4;
+ }
+ UINT8 **ppOutputLine = (UINT8**)malloc(sizeof(UINT8*)*nBands);
+ UINT8 *ppOutputBuffer = (UINT8*)malloc(type_size*view_width*nBands);
+ for(i = 0; i < nBands; i++)
+ ppOutputLine[i] = ppOutputBuffer + i*type_size*view_width;
+
+ for (int row = 0; row < view_height; row++)
+ {
+ NCSEcwReadStatus eError = NCScbmReadViewLineBILEx(this->pNCSFileView, eType, (void**)ppOutputLine);
+ if( eError != NCS_SUCCESS)
+ {
+ free(ppOutputLine);
+ free(ppOutputBuffer);
+ return IM_ERR_DATA;
+ }
+
+ iCopyDataBuffer(ppOutputLine, (imbyte*)this->line_buffer, nBands, view_width, type_size);
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ {
+ free(ppOutputLine);
+ free(ppOutputBuffer);
+ return IM_ERR_COUNTER;
+ }
+ }
+
+ free(ppOutputLine);
+ free(ppOutputBuffer);
+ return IM_ERR_NONE;
+}
+
+int imFormatECW::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ (void)compression;
+ (void)color_mode;
+ (void)data_type;
+ return IM_ERR_DATA;
+
+ //int color_space = imColorModeSpace(color_mode);
+
+ //if (color_space != IM_GRAY && color_space != IM_RGB)// && color_space != IM_LUV)
+ // return IM_ERR_DATA;
+ //
+ //if (data_type != IM_BYTE && data_type != IM_USHORT && data_type != IM_FLOAT)
+ // return IM_ERR_DATA;
+
+ //if (!compression || compression[0] == 0)
+ // return IM_ERR_NONE;
+
+ //if (!imStrEqual(compression, "JPEG-2000"))
+ // return IM_ERR_COMPRESS;
+
+ //return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_gif.cpp b/im/src/im_format_gif.cpp
new file mode 100755
index 0000000..caadd0f
--- /dev/null
+++ b/im/src/im_format_gif.cpp
@@ -0,0 +1,1510 @@
+/** \file
+ * \brief GIF - Graphics Interchange Format
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_gif.cpp,v 1.5 2009/08/23 23:57:51 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+
+static const int InterlacedOffset[4] = { 0, 4, 2, 1 }, /* The way Interlaced image should */
+ InterlacedJumps[4] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
+
+#define GIF_STAMP "GIF" /* First chars in file - GIF stamp. */
+#define GIF_VERSION "89a" /* First chars in file - GIF stamp. */
+
+#define GIF_LZ_BITS 12
+
+#define GIF_LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
+#define GIF_FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
+#define GIF_FIRST_CODE 4097 /* Impossible code, to signal first. */
+#define GIF_NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
+
+#define GIF_HT_KEY_MASK 0x1FFF /* 13bits keys */
+#define GIF_HT_KEY_NUM_BITS 13 /* 13bits keys */
+#define GIF_HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
+#define GIF_HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
+
+/* GIF89 extension function codes */
+#define COMMENT_EXT_FUNC_CODE 0xFE /* comment */
+#define GRAPHICS_EXT_FUNC_CODE 0xF9 /* graphics control */
+#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
+#define APPLICATION_EXT_FUNC_CODE 0xFF /* application block */
+
+/* The 32 bits of the integer are divided into two parts for the key & code: */
+/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
+/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
+#define GIF_HT_GET_KEY(l) (l >> 12)
+#define GIF_HT_GET_CODE(l) (l & 0x0FFF)
+#define GIF_HT_PUT_KEY(l) (l << 12)
+#define GIF_HT_PUT_CODE(l) (l & 0x0FFF)
+
+struct iGIFData
+{
+ unsigned char global_colors[256 * 3]; /* global color table if any */
+ int global_num_colors, /* global color table number of colors */
+ offset, /* image offset */
+ step, /* interlaced step */
+ interlaced, /* image is interlaced or not */
+ screen_width,
+ screen_height,
+ start_offset[512], /* offset of first block */
+ ClearCode, /* The CLEAR LZ code. */
+ BitsPerPixel, /* Bits per pixel (Codes uses at list this + 1). */
+ EOFCode, /* The EOF LZ code. */
+ RunningCode, /* The next code algorithm can generate. */
+ RunningBits, /* The number of bits required to represent RunningCode. */
+ MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
+ LastCode, /* The code before the current code. */
+ CrntCode, /* Current algorithm code. */
+ StackPtr, /* For character stack (see below). */
+ CrntShiftState; /* Number of bits in CrntShiftDWord. */
+ unsigned char Buf[256]; /* Compressed input is buffered here. */
+ unsigned int CrntShiftDWord; /* For bytes decomposition into codes. */
+ unsigned char Stack[GIF_LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
+ unsigned char Suffix[GIF_LZ_MAX_CODE+1]; /* So we can trace the codes. */
+ unsigned int Prefix[GIF_LZ_MAX_CODE+1];
+ unsigned int HTable[GIF_HT_SIZE]; /* hash table for the compression only, when using LZW */
+};
+
+/******************************************************************************
+* Routine to generate an HKey for the hashtable out of the given unique key. *
+* The given Key is assumed to be 20 bits as follows: lower 8 bits are the *
+* new postfix character, while the upper 12 bits are the prefix code. *
+* Because the average hit ratio is only 2 (2 hash references per entry), *
+* evaluating more complex keys (such as twin prime keys) does not worth it! *
+******************************************************************************/
+static int iGIFHashKeyItem(unsigned int Item)
+{
+ return ((Item >> 12) ^ Item) & GIF_HT_KEY_MASK;
+}
+
+/******************************************************************************
+* Routine to insert a new Item into the HashTable. The data is assumed to be *
+* new one. *
+******************************************************************************/
+static void iGIFInsertHashTable(unsigned int *HTable, unsigned int Key, int Code)
+{
+ int HKey = iGIFHashKeyItem(Key);
+
+ while (GIF_HT_GET_KEY(HTable[HKey]) != 0xFFFFFL)
+ {
+ HKey = (HKey + 1) & GIF_HT_KEY_MASK;
+ }
+
+ HTable[HKey] = GIF_HT_PUT_KEY(Key) | GIF_HT_PUT_CODE(Code);
+}
+
+/******************************************************************************
+* Routine to test if given Key exists in HashTable and if so returns its code *
+* Returns the Code if key was found, -1 if not. *
+******************************************************************************/
+static int iGIFExistsHashTable(unsigned int *HTable, unsigned int Key)
+{
+ int HKey = iGIFHashKeyItem(Key);
+ unsigned int HTKey;
+
+ while ((HTKey = GIF_HT_GET_KEY(HTable[HKey])) != 0xFFFFFL)
+ {
+ if (Key == HTKey)
+ return GIF_HT_GET_CODE(HTable[HKey]);
+
+ HKey = (HKey + 1) & GIF_HT_KEY_MASK;
+ }
+
+ return -1;
+}
+
+/******************************************************************************
+* This routines buffers the given characters until 255 characters are ready *
+* to be output. If Code is equal to -1 the buffer is flushed (EOF). *
+* The buffer is Dumped with first byte as its size, as GIF format requires. *
+******************************************************************************/
+static int iGIFBufferedOutput(imBinFile* handle, unsigned char *Buf, int c)
+{
+ if (c == GIF_FLUSH_OUTPUT)
+ {
+ /* Flush everything out. */
+ if (Buf[0] != 0)
+ imBinFileWrite(handle, Buf, Buf[0] + 1, 1);
+
+ /* Mark end of compressed data, by an empty block (see GIF doc): */
+ Buf[0] = 0;
+ imBinFileWrite(handle, Buf, 1, 1);
+ }
+ else
+ {
+ if (Buf[0] == 255)
+ {
+ /* Dump out this buffer - it is full: */
+ imBinFileWrite(handle, Buf, Buf[0] + 1, 1);
+ Buf[0] = 0;
+ }
+
+ Buf[++Buf[0]] = (unsigned char)c;
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+static int iGIFWriteNetscapeApplication(imBinFile* handle, short iterations)
+{
+ /* record type byte */
+ imBinFileWrite(handle, (void*)"!", 1, 1);
+
+ /* block label */
+ imBinFileWrite(handle, (void*)"\xFF", 1, 1);
+
+ /* block size */
+ imBinFileWrite(handle, (void*)"\x0B", 1, 1);
+
+ /* application identifier + athentication code */
+ imBinFileWrite(handle, (void*)"NETSCAPE2.0", 11, 1);
+
+ /* sub block size */
+ imBinFileWrite(handle, (void*)"\x3", 1, 1);
+
+ /* ??? */
+ imBinFileWrite(handle, (void*)"\x1", 1, 1);
+
+ /* iterations */
+ imBinFileWrite(handle, &iterations, 1, 2);
+
+ /* block terminator */
+ imBinFileWrite(handle, (void*)"\0", 1, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+/******************************************************************************
+* The LZ compression output routine: *
+* This routine is responsable for the compression of the bit stream into *
+* 8 bits (bytes) packets. *
+******************************************************************************/
+static int iGIFCompressOutput(iGIFData* igif, imBinFile* handle, int Code)
+{
+ int error = IM_ERR_NONE;
+
+ if (Code == GIF_FLUSH_OUTPUT)
+ {
+ while (igif->CrntShiftState > 0)
+ {
+ /* Get Rid of what is left in DWord, and flush it. */
+ error = iGIFBufferedOutput(handle, igif->Buf, igif->CrntShiftDWord & 0xff);
+ igif->CrntShiftDWord >>= 8;
+ igif->CrntShiftState -= 8;
+ }
+ igif->CrntShiftState = 0; /* For next time. */
+ error = iGIFBufferedOutput(handle, igif->Buf, GIF_FLUSH_OUTPUT);
+ }
+ else
+ {
+ igif->CrntShiftDWord |= ((int) Code) << igif->CrntShiftState;
+ igif->CrntShiftState += igif->RunningBits;
+ while (igif->CrntShiftState >= 8)
+ {
+ /* Dump out full bytes: */
+ error = iGIFBufferedOutput(handle, igif->Buf, igif->CrntShiftDWord & 0xff);
+ igif->CrntShiftDWord >>= 8;
+ igif->CrntShiftState -= 8;
+ }
+ }
+
+ /* If code cannt fit into RunningBits bits, must raise its size. Note */
+ /* however that codes above 4095 are used for special signaling. */
+ if (igif->RunningCode >= igif->MaxCode1 && Code <= GIF_LZ_MAX_CODE)
+ {
+ igif->MaxCode1 = 1 << ++igif->RunningBits;
+ }
+
+ return error;
+}
+
+/******************************************************************************
+* The LZ compression routine: *
+* This version compress the given buffer Line of length LineLen. *
+* This routine can be called few times (one per scan line, for example), in *
+* order the complete the whole image. *
+******************************************************************************/
+static int iGIFCompressLine(iGIFData* igif, imBinFile* handle, unsigned char *Line, int LineLen)
+{
+ int i = 0, CrntCode, NewCode;
+ unsigned int NewKey;
+ unsigned char Pixel;
+
+ if (igif->CrntCode == GIF_FIRST_CODE) /* Its first time! */
+ CrntCode = Line[i++];
+ else
+ CrntCode = igif->CrntCode; /* Get last code in compression. */
+
+ while (i < LineLen)
+ { /* Decode LineLen items. */
+ Pixel = Line[i++]; /* Get next pixel from stream. */
+ /* Form a new unique key to search hash table for the code combines */
+ /* CrntCode as Prefix string with Pixel as postfix char. */
+ NewKey = (((unsigned int) CrntCode) << 8) + Pixel;
+
+ if ((NewCode = iGIFExistsHashTable(igif->HTable, NewKey)) >= 0)
+ {
+ /* This Key is already there, or the string is old one, so */
+ /* simple take new code as our CrntCode: */
+ CrntCode = NewCode;
+ }
+ else
+ {
+ /* Put it in hash table, output the prefix code, and make our */
+ /* CrntCode equal to Pixel. */
+ if (iGIFCompressOutput(igif, handle, CrntCode) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ CrntCode = Pixel;
+
+ /* If however the HashTable if full, we send a clear first and */
+ /* Clear the hash table. */
+ if (igif->RunningCode >= GIF_LZ_MAX_CODE)
+ {
+ /* Time to do some clearance: */
+ if (iGIFCompressOutput(igif, handle, igif->ClearCode) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ igif->RunningCode = igif->EOFCode + 1;
+ igif->RunningBits = igif->BitsPerPixel + 1;
+ igif->MaxCode1 = 1 << igif->RunningBits;
+ memset(igif->HTable, 0xFF, GIF_HT_SIZE * sizeof(int));
+ }
+ else
+ {
+ /* Put this unique key with its relative Code in hash table: */
+ iGIFInsertHashTable(igif->HTable, NewKey, igif->RunningCode++);
+ }
+ }
+ }
+
+ /* Preserve the current state of the compression algorithm: */
+ igif->CrntCode = CrntCode;
+
+ return IM_ERR_NONE;
+}
+
+/******************************************************************************
+* This routines read one gif data block at a time and buffers it internally *
+* so that the decompression routine could access it. *
+* The routine returns the next byte from its internal buffer (or read next *
+* block in if buffer empty). *
+******************************************************************************/
+static int iGIFBufferedInput(imBinFile* handle, unsigned char *Buf, unsigned char *NextByte)
+{
+ if (Buf[0] == 0)
+ {
+ /* Needs to read the next buffer - this one is empty: */
+ imBinFileRead(handle, Buf, 1, 1);
+ imBinFileRead(handle, &Buf[1], Buf[0], 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ *NextByte = Buf[1];
+ Buf[1] = 2; /* We use now the second place as last char read! */
+ Buf[0]--;
+ }
+ else
+ {
+ *NextByte = Buf[Buf[1]++];
+ Buf[0]--;
+ }
+
+ return IM_ERR_NONE;
+}
+
+/******************************************************************************
+* The LZ decompression input routine: *
+* This routine is responsable for the decompression of the bit stream from *
+* 8 bits (bytes) packets, into the real codes. *
+******************************************************************************/
+static int iGIFDecompressInput(iGIFData* igif, imBinFile* handle, int *Code)
+{
+ unsigned char NextByte;
+ static unsigned int CodeMasks[] =
+ {
+ 0x0000, 0x0001, 0x0003, 0x0007,
+ 0x000f, 0x001f, 0x003f, 0x007f,
+ 0x00ff, 0x01ff, 0x03ff, 0x07ff,
+ 0x0fff
+ };
+
+ while (igif->CrntShiftState < igif->RunningBits)
+ {
+ /* Needs to get more bytes from input stream for next code: */
+ if (iGIFBufferedInput(handle, igif->Buf, &NextByte) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ igif->CrntShiftDWord |= ((unsigned int) NextByte) << igif->CrntShiftState;
+ igif->CrntShiftState += 8;
+ }
+
+ *Code = igif->CrntShiftDWord & CodeMasks[igif->RunningBits];
+
+ igif->CrntShiftDWord >>= igif->RunningBits;
+ igif->CrntShiftState -= igif->RunningBits;
+
+ /* If code cannt fit into RunningBits bits, must raise its size. Note */
+ /* however that codes above 4095 are used for special signaling. */
+ if (++(igif->RunningCode) > igif->MaxCode1 && igif->RunningBits < GIF_LZ_BITS)
+ {
+ igif->MaxCode1 <<= 1;
+ igif->RunningBits++;
+ }
+
+ return IM_ERR_NONE;
+}
+
+/******************************************************************************
+* Routine to trace the Prefixes linked list until we get a prefix which is *
+* not code, but a pixel value (less than ClearCode). Returns that pixel value.*
+* If image is defective, we might loop here forever, so we limit the loops to *
+* the maximum possible if image O.k. - LZ_MAX_CODE times. *
+******************************************************************************/
+static int iGIFGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode)
+{
+ int i = 0;
+
+ while (Code > ClearCode && i++ <= GIF_LZ_MAX_CODE)
+ Code = Prefix[Code];
+
+ return Code;
+}
+
+static int iGIFDecompressLine(iGIFData* igif, imBinFile* handle, unsigned char *Line, int LineLen)
+{
+ int i = 0, j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
+ unsigned char *Stack, *Suffix;
+ unsigned int *Prefix;
+
+ StackPtr = igif->StackPtr;
+ Prefix = igif->Prefix;
+ Suffix = igif->Suffix;
+ Stack = igif->Stack;
+ EOFCode = igif->EOFCode;
+ ClearCode = igif->ClearCode;
+ LastCode = igif->LastCode;
+
+ if (StackPtr != 0)
+ {
+ /* Let pop the stack off before continueing to read the gif file: */
+ while (StackPtr != 0 && i < LineLen)
+ Line[i++] = Stack[--StackPtr];
+ }
+
+ while (i < LineLen)
+ {
+ /* Decode LineLen items. */
+ if (iGIFDecompressInput(igif, handle, &CrntCode))
+ return IM_ERR_ACCESS;
+
+ if (CrntCode == EOFCode)
+ {
+ /* Note however that usually we will not be here as we will stop */
+ /* decoding as soon as we got all the pixel, or EOF code will */
+ /* not be read at all, and DGifGetLine/Pixel clean everything. */
+ if (i != LineLen - 1)
+ return IM_ERR_ACCESS;
+
+ i++;
+ }
+ else if (CrntCode == ClearCode)
+ {
+ /* We need to start over again: */
+ for (j = 0; j <= GIF_LZ_MAX_CODE; j++)
+ Prefix[j] = GIF_NO_SUCH_CODE;
+
+ igif->RunningCode = igif->EOFCode + 1;
+ igif->RunningBits = igif->BitsPerPixel + 1;
+ igif->MaxCode1 = 1 << igif->RunningBits;
+ LastCode = igif->LastCode = GIF_NO_SUCH_CODE;
+ }
+ else
+ {
+ /* Its regular code - if in pixel range simply add it to output */
+ /* stream, otherwise trace to codes linked list until the prefix */
+ /* is in pixel range: */
+ if (CrntCode < ClearCode)
+ {
+ /* This is simple - its pixel scalar, so add it to output: */
+ Line[i++] = (unsigned char)CrntCode;
+ }
+ else
+ {
+ /* Its a code to needed to be traced: trace the linked list */
+ /* until the prefix is a pixel, while pushing the suffix */
+ /* pixels on our stack. If we done, pop the stack in reverse */
+ /* (thats what stack is good for!) order to output. */
+ if (Prefix[CrntCode] == GIF_NO_SUCH_CODE)
+ {
+ /* Only allowed if CrntCode is exactly the running code: */
+ /* In that case CrntCode = XXXCode, CrntCode or the */
+ /* prefix code is last code and the suffix char is */
+ /* exactly the prefix of last code! */
+ if (CrntCode == igif->RunningCode - 2)
+ {
+ CrntPrefix = LastCode;
+ Suffix[igif->RunningCode - 2] =
+ Stack[StackPtr++] = (unsigned char)iGIFGetPrefixChar(Prefix, LastCode, ClearCode);
+ }
+ else
+ return IM_ERR_ACCESS;
+ }
+ else
+ CrntPrefix = CrntCode;
+
+ /* Now (if image is O.K.) we should not get an NO_SUCH_CODE */
+ /* During the trace. As we might loop forever, in case of */
+ /* defective image, we count the number of loops we trace */
+ /* and stop if we got LZ_MAX_CODE. obviously we can not */
+ /* loop more than that. */
+ j = 0;
+ while (j++ <= GIF_LZ_MAX_CODE && CrntPrefix > ClearCode && CrntPrefix <= GIF_LZ_MAX_CODE)
+ {
+ Stack[StackPtr++] = Suffix[CrntPrefix];
+ CrntPrefix = Prefix[CrntPrefix];
+ }
+
+ if (j >= GIF_LZ_MAX_CODE || CrntPrefix > GIF_LZ_MAX_CODE)
+ return IM_ERR_ACCESS;
+
+ /* Push the last character on stack: */
+ Stack[StackPtr++] = (unsigned char)CrntPrefix;
+
+ /* Now lets pop all the stack into output: */
+ while (StackPtr != 0 && i < LineLen)
+ Line[i++] = Stack[--StackPtr];
+ }
+
+ if (LastCode != GIF_NO_SUCH_CODE)
+ {
+ Prefix[igif->RunningCode - 2] = LastCode;
+
+ if (CrntCode == igif->RunningCode - 2)
+ {
+ /* Only allowed if CrntCode is exactly the running code: */
+ /* In that case CrntCode = XXXCode, CrntCode or the */
+ /* prefix code is last code and the suffix char is */
+ /* exactly the prefix of last code! */
+ Suffix[igif->RunningCode - 2] = (unsigned char)iGIFGetPrefixChar(Prefix, LastCode, ClearCode);
+ }
+ else
+ {
+ Suffix[igif->RunningCode - 2] = (unsigned char)iGIFGetPrefixChar(Prefix, CrntCode, ClearCode);
+ }
+ }
+
+ LastCode = CrntCode;
+ }
+ }
+
+ igif->LastCode = LastCode;
+ igif->StackPtr = StackPtr;
+
+ return IM_ERR_NONE;
+}
+
+/*******************************************
+* Skip sub-blocks until terminator found *
+********************************************/
+static int iGIFSkipSubBlocks(imBinFile* handle)
+{
+ unsigned char byte_value;
+ do
+ {
+ /* reads the number of bytes of the block or the terminator */
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* jump number of bytes, ignores the contents */
+ if (byte_value) imBinFileSeekOffset(handle, byte_value);
+ }while (byte_value != 0);
+
+ return IM_ERR_NONE;
+}
+
+static int iGIFSkipImage(imBinFile* handle, int *image_count, int *terminate)
+{
+ int found_image = 0;
+ unsigned char byte_value;
+
+ *terminate = 0;
+ do
+ {
+ /* reads the record type byte */
+ byte_value = 0;
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ switch (byte_value)
+ {
+ case ',': /* image description */
+ /* jump 8 bytes */
+ imBinFileSeekOffset(handle, 8);
+
+ /* reads the image information byte */
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ if (byte_value & 0x80)
+ {
+ int bpp = (byte_value & 0x07) + 1;
+ int num_colors = 1 << bpp;
+
+ /* skip the color table */
+ imBinFileSeekOffset(handle, 3*num_colors);
+ }
+
+ /* jump 1 byte (LZW Min Code) */
+ imBinFileSeekOffset(handle, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* skip sub blocks */
+ if (iGIFSkipSubBlocks(handle) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ /* one more image */
+ found_image = 1;
+ (*image_count)++;
+ break;
+ case '!': /* extension */
+ /* jump 1 byte (label) */
+ imBinFileSeekOffset(handle, 1);
+
+ /* skip sub blocks */
+ if (iGIFSkipSubBlocks(handle) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ break;
+ case ';': /* terminate */
+ default: /* probably EOF */
+ *terminate = 1;
+ break;
+ }
+
+ } while (!(*terminate) && (!found_image));
+
+ if (!found_image && *image_count == 0)
+ return IM_ERR_FORMAT;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+static void iGIFReadGraphicsControl(imBinFile* handle, imAttribTable* attrib_table)
+{
+ unsigned char byte_value;
+ unsigned short word_value;
+
+ /* jump 1 bytes (size) */
+ imBinFileSeekOffset(handle, 1);
+
+ /* reads the packed descrition */
+ imBinFileRead(handle, &byte_value, 1, 1);
+ if (imBinFileError(handle))
+ return;
+
+ /* user input */
+ if (byte_value & 0x02)
+ attrib_table->Set("UserInput", IM_BYTE, 1, "\x1");
+
+ /* disposal */
+ if (byte_value & 0x1C)
+ {
+ char* disposal;
+ int disp = (byte_value & 0x1C) >> 2;
+
+ switch (disp)
+ {
+ default:
+ disposal = "UNDEF";
+ break;
+ case 0x01:
+ disposal = "LEAVE";
+ break;
+ case 0x02:
+ disposal = "RBACK";
+ break;
+ case 0x04:
+ disposal = "RPREV";
+ break;
+ }
+
+ attrib_table->Set("Disposal", IM_BYTE, -1, disposal);
+ }
+
+ /* delay time */
+ imBinFileRead(handle, &word_value, 1, 2);
+ if (word_value)
+ attrib_table->Set("Delay", IM_USHORT, 1, &word_value);
+
+ /* transparency index */
+ if (byte_value & 0x01)
+ {
+ imBinFileRead(handle, &byte_value, 1, 1);
+ attrib_table->Set("TransparencyIndex", IM_BYTE, 1, &byte_value);
+ }
+ else
+ imBinFileSeekOffset(handle, 1);
+
+ /* jump 1 bytes (terminator) */
+ imBinFileSeekOffset(handle, 1);
+}
+
+static int iGIFReadApplication(imBinFile* handle, imAttribTable* attrib_table)
+{
+ char identifier[9];
+
+ /* jump 1 byte (size) */
+ imBinFileSeekOffset(handle, 1);
+
+ /* reads the application identifier */
+ imBinFileRead(handle, identifier, 8, 1);
+ if (identifier[7] != 0)
+ identifier[8] = 0;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (imStrEqual(identifier, "NETSCAPE"))
+ {
+ unsigned char authentication[4];
+ /* reads the application authentication code */
+ imBinFileRead(handle, authentication, 3, 1);
+ authentication[3] = 0;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (strcmp((char*)authentication, "2.0") == 0)
+ {
+ unsigned short word_value;
+
+ /* jump 2 bytes (size + 1) */
+ imBinFileSeekOffset(handle, 2);
+
+ /* reads the number of iterations */
+ imBinFileRead(handle, &word_value, 1, 2);
+
+ attrib_table->Set("Iterations", IM_USHORT, 1, &word_value);
+
+ /* jump 1 byte (terminator) */
+ imBinFileSeekOffset(handle, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ /* Skip remaining blocks */
+ if (iGIFSkipSubBlocks(handle) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ }
+ }
+ else
+ {
+ /* jump 3 bytes (authentication code) */
+ imBinFileSeekOffset(handle, 3);
+
+ /* Skip remaining blocks */
+ if (iGIFSkipSubBlocks(handle) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+static int iGIFReadComment(imBinFile* handle, imAttribTable* attrib_table)
+{
+ unsigned char byte_value, buffer[255*100] = "", *buffer_ptr;
+ int size = 0;
+
+ buffer_ptr = &buffer[0];
+
+ do
+ {
+ /* reads the number of bytes of the block or the terminator */
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* reads data */
+ if (byte_value)
+ {
+ imBinFileRead(handle, buffer_ptr, byte_value, 1);
+
+ if (buffer_ptr[byte_value-1] == 0)
+ {
+ size += byte_value-1;
+ buffer_ptr += byte_value-1;
+ }
+ else
+ {
+ size += byte_value;
+ buffer_ptr += byte_value;
+ }
+ }
+
+ }while (byte_value != 0);
+
+ if (buffer[0] != 0)
+ attrib_table->Set("Description", IM_BYTE, size, buffer);
+
+ return IM_ERR_NONE;
+}
+
+static int iGIFReadExtension(imBinFile* handle, imAttribTable* attrib_table)
+{
+ unsigned char byte_value;
+
+ /* read block label */
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ if (byte_value == 0xF9)
+ {
+ /* Graphics Control Extension */
+ iGIFReadGraphicsControl(handle, attrib_table);
+ }
+ else if (byte_value == 0xFE)
+ {
+ /* Comment Extension */
+ if (iGIFReadComment(handle, attrib_table) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ }
+ else if (byte_value == 0xFF)
+ {
+ /* Application Extension */
+ if (iGIFReadApplication(handle, attrib_table) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ /* skip sub blocks */
+ if (iGIFSkipSubBlocks(handle) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+static int iGIFWriteComment(imBinFile* handle, unsigned char *buffer, int size)
+{
+ unsigned char byte_value;
+
+ /* record type byte */
+ imBinFileWrite(handle, (void*)"!", 1, 1);
+
+ /* block label */
+ imBinFileWrite(handle, (void*)"\xFE", 1, 1);
+
+ while (size > 0)
+ {
+ if (size > 255)
+ byte_value = 255;
+ else
+ byte_value = (unsigned char)size;
+
+ /* sub block size */
+ imBinFileWrite(handle, &byte_value, 1, 1);
+
+ /* sub block data */
+ imBinFileWrite(handle, buffer, byte_value, 1);
+
+ buffer += byte_value;
+ size -= byte_value;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+
+ /* block terminator */
+ imBinFileWrite(handle, (void*)"\0", 1, 1);
+
+ return IM_ERR_NONE;
+}
+
+static int iGIFWriteGraphicsControl(imBinFile* handle, imAttribTable* attrib_table)
+{
+ const void *attrib_user_input, *attrib_disposal, *attrib_delay, *attrib_transparency;
+ unsigned char byte_value;
+
+ attrib_user_input = attrib_table->Get("UserInput");
+ attrib_disposal = attrib_table->Get("Disposal");
+ attrib_delay = attrib_table->Get("Delay");
+ attrib_transparency = attrib_table->Get("TransparencyIndex");
+
+ /* Writes the Graphics Control Extension */
+ if (attrib_user_input || attrib_disposal || attrib_delay || attrib_transparency)
+ {
+ unsigned short word_value;
+
+ /* record type byte */
+ imBinFileWrite(handle, (void*)"!", 1, 1);
+
+ /* block label */
+ imBinFileWrite(handle, (void*)"\xF9", 1, 1);
+
+ /* block size */
+ imBinFileWrite(handle, (void*)"\x04", 1, 1);
+
+ byte_value = 0;
+
+ /* user input flag */
+ if (attrib_user_input && *(unsigned char*)attrib_user_input == 1)
+ byte_value |= 0x02;
+
+ /* transparency flag */
+ if (attrib_transparency)
+ byte_value |= 0x01;
+
+ /* disposal flag */
+ if (attrib_disposal)
+ {
+ int disp = 0;
+ if (imStrEqual((char*)attrib_disposal, "LEAVE"))
+ disp = 0x01;
+ else if (imStrEqual((char*)attrib_disposal, "RBACK"))
+ disp = 0x02;
+ else if (imStrEqual((char*)attrib_disposal, "RPREV"))
+ disp = 0x04;
+
+ disp = disp << 2;
+ byte_value |= disp;
+ }
+
+ /* packed */
+ imBinFileWrite(handle, &byte_value, 1, 1);
+
+ /* delay time */
+ if (attrib_delay)
+ word_value = *(unsigned short*)attrib_delay;
+ else
+ word_value = 0;
+
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ /* transparency index */
+ if (attrib_transparency)
+ {
+ byte_value = *(unsigned char*)attrib_transparency;
+ imBinFileWrite(handle, &byte_value, 1, 1);
+ }
+ else
+ imBinFileWrite(handle, (void*)"\0", 1, 1);
+
+ /* terminator */
+ imBinFileWrite(handle, (void*)"\0", 1, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+static const char* iGIFCompTable[1] =
+{
+ "LZW"
+};
+
+class imFileFormatGIF: public imFileFormatBase
+{
+ imBinFile* handle;
+ iGIFData gif_data;
+
+ int GIFReadImageInfo();
+ int GIFWriteImageInfo();
+
+public:
+ imFileFormatGIF(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatGIF() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatGIF: public imFormat
+{
+public:
+ imFormatGIF()
+ :imFormat("GIF",
+ "Graphics Interchange Format",
+ "*.gif;",
+ iGIFCompTable,
+ 1,
+ 1)
+ {}
+ ~imFormatGIF() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatGIF(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+void imFormatRegisterGIF(void)
+{
+ imFormatRegister(new imFormatGIF());
+}
+
+int imFileFormatGIF::Open(const char* file_name)
+{
+ this->handle = imBinFileOpen(file_name);
+ if (this->handle == NULL)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ unsigned char sig[4];
+ if (!imBinFileRead(this->handle, sig, 3, 1))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ sig[3] = 0;
+ if (!imStrEqual((char*)sig, GIF_STAMP))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ /* ignore version */
+ imBinFileSeekOffset(handle, 3);
+
+ strcpy(this->compression, "LZW");
+
+ /* reads screen width and screen height */
+ imushort word_value;
+ imBinFileRead(handle, &word_value, 1, 2);
+ gif_data.screen_width = word_value;
+
+ imBinFileRead(handle, &word_value, 1, 2);
+ gif_data.screen_height = word_value;
+
+ /* reads color table information byte */
+ imbyte byte_value;
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ /* jump 2 bytes (bgcolor + aspect ratio) */
+ imBinFileSeekOffset(handle, 2);
+
+ /* global color table, if exists */
+ if (byte_value & 0x80)
+ {
+ int bpp = (byte_value & 0x07) + 1;
+ gif_data.global_num_colors = 1 << bpp;
+
+ /* reads the color palette */
+ imBinFileRead(handle, gif_data.global_colors, gif_data.global_num_colors * 3, 1);
+ }
+
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ /* count number of images */
+ int error, terminate;
+ this->image_count = 0;
+ do
+ {
+ // store each offset before counting images
+ gif_data.start_offset[this->image_count] = imBinFileTell(handle);
+ error = iGIFSkipImage(handle, &this->image_count, &terminate);
+ } while (!terminate && error == IM_ERR_NONE);
+
+ if (this->image_count == 0 || error != IM_ERR_NONE)
+ {
+ imBinFileClose(handle);
+ return error;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatGIF::New(const char* file_name)
+{
+ this->handle = imBinFileNew(file_name);
+ if (this->handle == NULL)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ /* writes the GIF STAMP and version - header */
+ imBinFileWrite(handle, (void*)GIF_STAMP, 3, 1); /* identifier */
+ imBinFileWrite(handle, (void*)GIF_VERSION, 3, 1); /* format version */
+
+ // File header will be written at the first image
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(this->handle);
+ return IM_ERR_ACCESS;
+ }
+
+ strcpy(this->compression, "LZW");
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatGIF::Close()
+{
+ if (this->is_new && !imBinFileError(this->handle))
+ imBinFileWrite(this->handle, (void*)";", 1, 1);
+
+ imBinFileClose(this->handle);
+}
+
+void* imFileFormatGIF::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatGIF::GIFReadImageInfo()
+{
+ imbyte byte_value;
+ imushort word_value;
+ int int_value;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ /* reads the image left position */
+ imBinFileRead(handle, &word_value, 1, 2);
+ if (word_value)
+ attrib_table->Set("XScreen", IM_USHORT, 1, &word_value);
+
+ /* reads the image top position */
+ imBinFileRead(handle, &word_value, 1, 2);
+ if (word_value)
+ attrib_table->Set("YScreen", IM_USHORT, 1, &word_value);
+
+ /* reads the image width */
+ imBinFileRead(handle, &word_value, 1, 2);
+ this->width = word_value;
+
+ /* reads the image height */
+ imBinFileRead(handle, &word_value, 1, 2);
+ this->height = word_value;
+
+ /* reads the image information byte */
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ gif_data.interlaced = (byte_value & 0x40)? 1: 0;
+ if (gif_data.interlaced)
+ {
+ int_value = 1;
+ attrib_table->Set("Interlaced", IM_INT, 1, &int_value);
+ }
+
+ this->file_color_mode = IM_MAP;
+ this->file_data_type = IM_BYTE;
+
+ /* local color table */
+ int num_colors;
+ unsigned char *colors;
+ unsigned char local_colors[256 * 3];
+
+ if (byte_value & 0x80)
+ {
+ int bpp = (byte_value & 0x07) + 1;
+ num_colors = 1 << bpp;
+ colors = local_colors;
+
+ /* reads the color table */
+ imBinFileRead(handle, local_colors, num_colors * 3, 1);
+ }
+ else if (gif_data.global_num_colors)
+ {
+ colors = gif_data.global_colors;
+ num_colors = gif_data.global_num_colors;
+ }
+ else
+ return IM_ERR_FORMAT;
+
+ long palette[256];
+ for (int c = 0; c < num_colors; c++)
+ {
+ palette[c] = imColorEncode(colors[c*3],
+ colors[c*3+1],
+ colors[c*3+2]);
+ }
+
+ imFileSetPalette(this, palette, num_colors);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatGIF::GIFWriteImageInfo()
+{
+ this->file_data_type = IM_BYTE;
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+ this->file_color_mode |= IM_TOPDOWN;
+
+ imAttribTable* attrib_table = AttribTable();
+ const void* attrib = attrib_table->Get("Interlaced");
+ if (attrib)
+ gif_data.interlaced = *(int*)attrib;
+
+ imBinFileWrite(handle, (void*)",", 1, 1); /* Image separator character. */
+
+ imushort word_value;
+
+ attrib = attrib_table->Get("XScreen");
+ if (attrib)
+ word_value = *(unsigned short*)attrib;
+ else
+ word_value = 0;
+ imBinFileWrite(handle, &word_value, 1, 2); /* image left */
+
+ attrib = attrib_table->Get("YScreen");
+ if (attrib)
+ word_value = *(unsigned short*)attrib;
+ else
+ word_value = 0;
+ imBinFileWrite(handle, &word_value, 1, 2); /* image top */
+
+ word_value = (unsigned short)this->width;
+ imBinFileWrite(handle, &word_value, 1, 2); /* image width */
+ word_value = (unsigned short)this->height;
+ imBinFileWrite(handle, &word_value, 1, 2); /* image height */
+
+ /* local color table */
+ imbyte byte_value = 0x80;
+ if (gif_data.interlaced)
+ byte_value |= 0x40;
+
+ int num_colors = 256;
+ if (imColorModeSpace(this->user_color_mode) == IM_MAP)
+ {
+ int bpp = 0, c = this->palette_count-1;
+ while (c) {c = c >> 1;bpp++;}
+ byte_value |= (bpp-1);
+ num_colors = 1 << bpp;
+ }
+ else
+ byte_value |= 0x07; /* 8 bits = 256 grays */
+
+ imBinFileWrite(handle, &byte_value, 1, 1); /* image information */
+
+ /* write color table */
+ unsigned char local_colors[256*3];
+ for (int c = 0; c < num_colors; c++) // write all data, even not used colors
+ {
+ unsigned char r, g, b;
+ imColorDecode(&r, &g, &b, this->palette[c]);
+ local_colors[c*3] = r;
+ local_colors[c*3+1] = g;
+ local_colors[c*3+2] = b;
+ }
+ imBinFileWrite(handle, local_colors, num_colors*3, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatGIF::ReadImageInfo(int index)
+{
+ imAttribTable* attrib_table = AttribTable();
+
+ /* must clear the attribute list, because it can have multiple images and
+ has many attributes that may exists only for specific images. */
+ attrib_table->RemoveAll();
+ imFileSetBaseAttributes(this);
+
+ if (gif_data.screen_width)
+ {
+ imushort word_value = (imushort)gif_data.screen_width;
+ attrib_table->Set("ScreenWidth", IM_USHORT, 1, &word_value);
+ }
+
+ if (gif_data.screen_height)
+ {
+ imushort word_value = (imushort)gif_data.screen_height;
+ attrib_table->Set("ScreenHeight", IM_USHORT, 1, &word_value);
+ }
+
+ /* jump to start offset of the image */
+ imBinFileSeekTo(handle, gif_data.start_offset[index]);
+
+ int found_image = 0;
+ imbyte byte_value;
+
+ int terminate = 0;
+ do
+ {
+ /* reads the record type byte */
+ byte_value = 0;
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ switch (byte_value)
+ {
+ case '!': /* 0x21 extension (appears before the image) */
+ if (iGIFReadExtension(handle, attrib_table) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ break;
+ case ',': /* 0x2C image description and color table */
+ if (GIFReadImageInfo() != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ /* we will read only this image for now, so break the loop */
+ found_image = 1;
+ break;
+ case ';': /* if terminate before find image return error */
+ default:
+ terminate = 1;
+ break;
+ }
+ } while (!terminate && !found_image);
+
+ if (!found_image)
+ return IM_ERR_ACCESS;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* reads the LZW Min code byte */
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ /* now initialize the compression control data */
+
+ gif_data.BitsPerPixel = byte_value;
+ gif_data.ClearCode = (1 << byte_value);
+ gif_data.EOFCode = gif_data.ClearCode + 1;
+ gif_data.RunningCode = gif_data.EOFCode + 1;
+ gif_data.RunningBits = byte_value + 1; /* Number of bits per code. */
+ gif_data.MaxCode1 = 1 << gif_data.RunningBits; /* Max. code + 1. */
+ gif_data.StackPtr = 0; /* No pixels on the pixel stack. */
+ gif_data.LastCode = GIF_NO_SUCH_CODE;
+ gif_data.CrntShiftState = 0; /* No information in CrntShiftDWord. */
+ gif_data.CrntShiftDWord = 0;
+ gif_data.Buf[0] = 0; /* Input Buffer empty. */
+
+ for (int i = 0; i <= GIF_LZ_MAX_CODE; i++)
+ gif_data.Prefix[i] = GIF_NO_SUCH_CODE;
+
+ gif_data.step = 0;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatGIF::WriteImageInfo()
+{
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+ this->file_color_mode |= IM_TOPDOWN;
+ this->file_data_type = this->user_data_type;
+
+ imAttribTable* attrib_table = AttribTable();
+ const void* attrib_data;
+ int attrib_size;
+
+ if (this->image_count == 0)
+ {
+ imushort word_value;
+
+ // write file header
+
+ /* logical screen descriptor */
+ attrib_data = attrib_table->Get("ScreenWidth");
+ if (attrib_data) word_value = *(imushort*)attrib_data;
+ else word_value = (imushort)this->width;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ attrib_data = attrib_table->Get("ScreenHeight");
+ if (attrib_data) word_value = *(imushort*)attrib_data;
+ else word_value = (imushort)this->height;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ imbyte byte_value = 0; /* no global color table, 0 colors */
+ imBinFileWrite(handle, &byte_value, 1, 1); /* screen information */
+ imBinFileWrite(handle, (void*)"\0\0", 2, 1); /* (bgcolor + aspect ratio) */
+ }
+
+ attrib_data = attrib_table->Get("Description", NULL, &attrib_size);
+ if (attrib_data)
+ {
+ if (iGIFWriteComment(handle, (imbyte*)attrib_data, attrib_size) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ }
+
+ attrib_data = attrib_table->Get("Iterations");
+ if (attrib_data)
+ {
+ if (iGIFWriteNetscapeApplication(handle, *(short*)attrib_data) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+ }
+
+ if (iGIFWriteGraphicsControl(handle, attrib_table) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ if (GIFWriteImageInfo() != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ /* initializes the hash table */
+ memset(gif_data.HTable, 0xFF, GIF_HT_SIZE * sizeof(int));
+
+ /* initializes compression data */
+
+ imbyte byte_value = 8;
+ imBinFileWrite(handle, &byte_value, 1, 1); /* Write the Code size to file. */
+
+ gif_data.Buf[0] = 0; /* Nothing was output yet. */
+ gif_data.BitsPerPixel = 8;
+ gif_data.ClearCode = (1 << 8);
+ gif_data.EOFCode = gif_data.ClearCode + 1;
+ gif_data.RunningBits = 8 + 1; /* Number of bits per code. */
+ gif_data.MaxCode1 = 1 << gif_data.RunningBits; /* Max. code + 1. */
+ gif_data.CrntCode = GIF_FIRST_CODE; /* Signal that this is first one! */
+ gif_data.CrntShiftState = 0; /* No information in CrntShiftDWord. */
+ gif_data.CrntShiftDWord = 0;
+
+ gif_data.RunningCode = gif_data.EOFCode + 1;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ gif_data.step = 0; /* interlaced step */
+
+ return iGIFCompressOutput(&gif_data, handle, gif_data.ClearCode);
+}
+
+int imFileFormatGIF::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading GIF...");
+
+ int row = 0, error;
+ for (int i = 0; i < this->height; i++)
+ {
+ error = iGIFDecompressLine(&gif_data, handle, (imbyte*)this->line_buffer, this->width);
+ if (error != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+
+ if (gif_data.interlaced)
+ {
+ row += InterlacedJumps[gif_data.step];
+
+ if (row > this->height-1)
+ {
+ gif_data.step++;
+ row = InterlacedOffset[gif_data.step];
+ }
+ }
+ else
+ row++;
+ }
+
+ /* Skip remaining empty blocks of the image data */
+ if (iGIFSkipSubBlocks(handle) != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatGIF::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing GIF...");
+
+ int row = 0, error;
+ for (int i = 0; i < this->height; i++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ error = iGIFCompressLine(&gif_data, handle, (imbyte*)this->line_buffer, this->width);
+
+ if (error != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+
+ if (gif_data.interlaced)
+ {
+ row += InterlacedJumps[gif_data.step];
+
+ if (row > this->height-1)
+ {
+ gif_data.step++;
+ row = InterlacedOffset[gif_data.step];
+ }
+ }
+ else
+ row++;
+ }
+
+ /* writes the end picture code */
+ iGIFCompressOutput(&gif_data, handle, gif_data.CrntCode);
+ iGIFCompressOutput(&gif_data, handle, gif_data.EOFCode);
+ iGIFCompressOutput(&gif_data, handle, GIF_FLUSH_OUTPUT);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ this->image_count++;
+ return IM_ERR_NONE;
+}
+
+int imFormatGIF::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space != IM_MAP && color_space != IM_GRAY && color_space != IM_BINARY)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "LZW"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
+
diff --git a/im/src/im_format_ico.cpp b/im/src/im_format_ico.cpp
new file mode 100755
index 0000000..b10f30e
--- /dev/null
+++ b/im/src/im_format_ico.cpp
@@ -0,0 +1,660 @@
+/** \file
+ * \brief ICO - Windows Icon
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_ico.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+/*
+typedef struct
+{
+ WORD idReserved; // Reserved (must be 0)
+ WORD idType; // Resource Type (1 for icons)
+ WORD idCount; // How many images?
+ ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em)
+} ICONDIR, *LPICONDIR; // 6
+typedef struct
+{
+ BYTE bWidth; // Width, in pixels, of the image
+ BYTE bHeight; // Height, in pixels, of the image
+ BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
+ BYTE bReserved; // Reserved ( must be 0)
+ WORD wPlanes; // Color Planes
+ WORD wBitCount; // Bits per pixel
+ DWORD dwBytesInRes; // How many bytes in this resource?
+ DWORD dwImageOffset; // Where in the file is this image?
+} ICONDIRENTRY, *LPICONDIRENTRY; // 16
+typdef struct
+{
+ BITMAPINFOHEADER icHeader; // DIB header
+ RGBQUAD icColors[1]; // Color table
+ BYTE icXOR[1]; // DIB bits for XOR mask
+ BYTE icAND[1]; // DIB bits for AND mask (1 bpp)
+} ICONIMAGE, *LPICONIMAGE;
+*/
+
+static const char* iICOCompTable[1] =
+{
+ "NONE"
+};
+
+class imFileFormatICO: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ unsigned short bpp; /* number of bits per pixel */
+ unsigned int offset[10],
+ next_offset;
+ int line_raw_size; // raw line size
+
+ int ReadPalette();
+ int WritePalette();
+ void FixRGBOrder();
+
+public:
+ imFileFormatICO(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatICO() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatICO: public imFormat
+{
+public:
+ imFormatICO()
+ :imFormat("ICO",
+ "Windows Icon",
+ "*.ico;",
+ iICOCompTable,
+ 1,
+ 1)
+ {}
+ ~imFormatICO() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatICO(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+
+void imFormatRegisterICO(void)
+{
+ imFormatRegister(new imFormatICO());
+}
+
+int imFileFormatICO::Open(const char* file_name)
+{
+ unsigned short word;
+
+ /* opens the binary file for reading with intel byte order */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ /* reads the reserved value */
+ imBinFileRead(handle, &word, 1, 2);
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (word != 0)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ /* reads the resource type */
+ imBinFileRead(handle, &word, 1, 2);
+ if (word != 1)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ /* reads the number of images */
+ imBinFileRead(handle, &word, 1, 2);
+
+ this->image_count = word > 10? 10: word;
+ strcpy(this->compression, "NONE");
+
+ for (int i = 0; i < this->image_count; i++)
+ {
+ /* skip ICONDIRENTRY data except image offset */
+ imBinFileSeekOffset(handle, 12);
+
+ /* reads the image offset */
+ imBinFileRead(handle, &this->offset[i], 1, 4);
+
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatICO::New(const char* file_name)
+{
+ /* opens the binary file for writing with intel byte order */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ imushort word_value = 0;
+ imBinFileWrite(handle, &word_value, 1, 2); /* reserved */
+ word_value = 1;
+ imBinFileWrite(handle, &word_value, 1, 2); /* resource type */
+ imBinFileWrite(handle, &word_value, 1, 2); /* number of images, at least one, must update at close */
+
+ this->next_offset = 6 + 5 * 16; // offset to the first image, room for 5 ICONDIRENTRY
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatICO::Close()
+{
+ if (this->is_new)
+ {
+ if (this->image_count > 1)
+ {
+ imBinFileSeekTo(handle, 4);
+ imushort word_value = (imushort)this->image_count;
+ imBinFileWrite(handle, &word_value, 1, 2); /* number of images */
+ }
+ }
+
+ imBinFileClose(handle);
+}
+
+void* imFileFormatICO::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatICO::ReadImageInfo(int index)
+{
+ this->file_data_type = IM_BYTE;
+ unsigned int dword_value;
+
+ if (index >= image_count)
+ return IM_ERR_DATA;
+
+ // offset + size
+ imBinFileSeekTo(handle, this->offset[index] + 4);
+
+ /* reads the image width */
+ imBinFileRead(handle, &dword_value, 1, 4);
+ this->width = (int)dword_value;
+
+ /* reads the image height */
+ imBinFileRead(handle, &dword_value, 1, 4);
+ this->height = (int)(dword_value / 2);
+
+ /* jump 2 bytes (planes) */
+ imBinFileSeekOffset(handle, 2);
+
+ // bpp
+ imBinFileRead(handle, &this->bpp, 1, 2);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ // sanity check
+ if (this->bpp != 1 && this->bpp != 4 && this->bpp != 8 &&
+ this->bpp != 24 && this->bpp != 32)
+ return IM_ERR_DATA;
+
+ if (this->bpp > 8)
+ {
+ this->file_color_mode = IM_RGB;
+ this->file_color_mode |= IM_PACKED;
+ if (this->bpp == 32)
+ this->file_color_mode |= IM_ALPHA;
+ }
+ else
+ {
+ this->file_color_mode = IM_MAP;
+ this->palette_count = 1 << bpp;
+ }
+
+ if (this->bpp < 8)
+ this->convert_bpp = this->bpp;
+
+ this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 4);
+ this->line_buffer_extra = 4; // room enough for padding
+
+ /* jump 8 bytes (compression, image size, resolution) */
+ imBinFileSeekOffset(handle, 16);
+
+ if (this->bpp <= 8)
+ {
+ /* reads the number of colors used */
+ imBinFileRead(handle, &dword_value, 1, 4);
+
+ /* updates the palette_count based on the number of colors used */
+ if (dword_value != 0 && (int)dword_value < this->palette_count)
+ this->palette_count = dword_value;
+
+ /* jump 4 bytes (important colors) */
+ imBinFileSeekOffset(handle, 4);
+ }
+ else
+ {
+ /* jump 8 bytes (used colors, important colors) */
+ imBinFileSeekOffset(handle, 8);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->bpp <= 8)
+ return ReadPalette();
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatICO::WriteImageInfo()
+{
+ this->file_data_type = IM_BYTE;
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+
+ if (this->image_count == 5)
+ return IM_ERR_DATA;
+
+ if (this->width > 255 || this->height > 255)
+ return IM_ERR_DATA;
+
+ if (this->file_color_mode == IM_BINARY)
+ {
+ this->bpp = 1;
+ this->convert_bpp = 1;
+ }
+ else if (this->file_color_mode == IM_RGB)
+ {
+ this->file_color_mode |= IM_PACKED;
+ if (imColorModeHasAlpha(this->user_color_mode))
+ {
+ this->file_color_mode |= IM_ALPHA;
+ this->bpp = 32;
+ }
+ else
+ this->bpp = 24;
+ }
+ else
+ this->bpp = 8;
+
+ this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 4);
+ this->line_buffer_extra = 4; // room enough for padding
+ int palette_size = (this->bpp > 8)? 0: this->palette_count*4;
+
+ imbyte byte_value;
+ imushort word_value;
+
+ /* updates the ICON directory entry */
+
+ imBinFileSeekTo(handle, 6 + this->image_count * 16); // ICONDIR + i * ICONDIRENTRY
+
+ byte_value = (imbyte)this->width;
+ imBinFileWrite(handle, &byte_value, 1, 1); /* width */
+ byte_value = (imbyte)this->height;
+ imBinFileWrite(handle, &byte_value, 1, 1); /* height */
+ byte_value = (imbyte)((this->bpp > 8)? 0: this->palette_count);
+ imBinFileWrite(handle, &byte_value, 1, 1); /* color count */
+ imBinFileWrite(handle, (void*)"\0", 1, 1); /* reserved */
+ word_value = 1;
+ imBinFileWrite(handle, &word_value, 1, 2); /* planes */
+ word_value = this->bpp;
+ imBinFileWrite(handle, &word_value, 1, 2); /* bit count */
+ int and_line_size = imFileLineSizeAligned(this->width, 1, 4);
+ int resource_size = 40 + palette_size + (line_raw_size + and_line_size) * this->height;
+ unsigned int dword_value = resource_size;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* resource size */
+ dword_value = this->next_offset;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* data offset */
+
+ this->offset[this->image_count] = this->next_offset;
+ this->next_offset += resource_size;
+
+ /* writes the image */
+
+ imBinFileSeekTo(handle, this->offset[this->image_count]);
+
+ dword_value = 40;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* header size */
+ dword_value = this->width;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* width */
+ dword_value = this->height*2;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* height */
+ word_value = 1;
+ imBinFileWrite(handle, &word_value, 1, 2); /* planes */
+ word_value = this->bpp;
+ imBinFileWrite(handle, &word_value, 1, 2); /* bpp */
+ dword_value = 0;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* compression */
+ dword_value = line_raw_size * this->height;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* data size */
+
+ imBinFileWrite(handle, (void*)"\0\0\0\0\0\0\0\0", 8, 1); /* resolution */
+
+ dword_value = (this->bpp > 8)? 0: this->palette_count;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* colors used */
+ dword_value = 0;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* colors important (all) */
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->bpp < 24)
+ return WritePalette();
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatICO::ReadPalette()
+{
+ /* reads the color palette */
+ unsigned char bmp_colors[256 * 4];
+ imBinFileRead(handle, bmp_colors, this->palette_count * 4, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * 4;
+ this->palette[c] = imColorEncode(bmp_colors[i + 2],
+ bmp_colors[i + 1],
+ bmp_colors[i]);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatICO::WritePalette()
+{
+ unsigned char bmp_colors[256 * 4];
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * 4;
+ imColorDecode(&bmp_colors[i + 2], &bmp_colors[i + 1], &bmp_colors[i], this->palette[c]);
+ bmp_colors[i + 3] = 0;
+ }
+
+ /* writes the color palette */
+ imBinFileWrite(handle, bmp_colors, this->palette_count * 4, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatICO::FixRGBOrder()
+{
+ if (this->bpp == 24)
+ {
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+ for (int x = 0; x < this->width; x++)
+ {
+ int c = x*3;
+ imbyte temp = byte_data[c]; // swap R and B
+ byte_data[c] = byte_data[c+2];
+ byte_data[c+2] = temp;
+ }
+ }
+ else /* bpp == 32 */
+ {
+ /* inverts the DWORD values if not intel */
+ if (imBinCPUByteOrder() == IM_BIGENDIAN)
+ imBinSwapBytes4(this->line_buffer, this->width);
+
+ unsigned int* dword_data = (unsigned int*)this->line_buffer;
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+
+ for (int x = 0; x < this->width; x++)
+ {
+ unsigned int dword_value = dword_data[x];
+ int c = x*4;
+ byte_data[c] = (imbyte)((0x00FF0000 & dword_value) >> 16);
+ byte_data[c+1] = (imbyte)((0x0000FF00 & dword_value) >> 8);
+ byte_data[c+2] = (imbyte)((0x000000FF & dword_value) >> 0);
+ byte_data[c+3] = (imbyte)((0xFF000000 & dword_value) >> 24);
+ }
+ }
+}
+
+static inline int PixelOffset(int is_top_down, int is_packed, int width, int height, int depth, int col, int row, int plane)
+{
+ if (is_top_down)
+ row = height-1 - row;
+
+ if (is_packed)
+ return row*width*depth + col*depth + plane;
+ else
+ return plane*width*height + row*width + col;
+}
+
+int imFileFormatICO::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading ICO...");
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imBinFileRead(handle, this->line_buffer, this->line_raw_size, 1);
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->bpp > 8)
+ FixRGBOrder();
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ if ((imColorModeHasAlpha(this->user_color_mode) && this->bpp!=32) || /* user has alpha and file does not have alpha -> alpha came from AND data */
+ imColorModeSpace(this->user_color_mode) == IM_MAP) /* or MAP */
+ {
+ int line_size = imFileLineSizeAligned(this->width, 1, 4);
+ int image_size = this->height*line_size;
+ imbyte* and_data = new imbyte[image_size];
+
+ imBinFileRead(handle, and_data, image_size, 1);
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ imbyte* and_data_line = and_data;
+ imbyte* user_data = (imbyte*)data;
+ unsigned long histo[256];
+ int depth = imColorModeDepth(this->user_color_mode);
+ int alpha_plane = 0;
+ if (imColorModeHasAlpha(this->user_color_mode))
+ alpha_plane = depth - 1;
+ else
+ memset(histo, 0, 256*sizeof(unsigned long));
+
+ for (int j = 0; j < this->height; j++)
+ {
+ for (int i = 0; i < this->width; i++)
+ {
+ int offset = PixelOffset(imColorModeIsTopDown(this->user_color_mode),
+ imColorModeIsPacked(this->user_color_mode),
+ this->width, this->height, depth, i, j, alpha_plane);
+
+ if (imColorModeHasAlpha(this->user_color_mode))
+ {
+ if (((and_data_line[i / 8] >> (7 - i % 8)) & 0x01))
+ user_data[offset] = 0;
+ else
+ user_data[offset] = 255;
+ }
+ else
+ {
+ /* the most repeated index with transparency will be the transparent index. */
+ if (((and_data_line[i / 8] >> (7 - i % 8)) & 0x01))
+ histo[user_data[offset]]++;
+ }
+ }
+ and_data_line += line_size;
+ }
+
+ if (imColorModeSpace(this->user_color_mode) == IM_MAP)
+ {
+ imbyte transp_index = 0;
+ unsigned long histo_max = histo[0];
+
+ for (int i = 1; i < 256; i++)
+ {
+ if (histo_max < histo[i])
+ {
+ histo_max = histo[i];
+ transp_index = (imbyte)i;
+ }
+ }
+ AttribTable()->Set("TransparencyIndex", IM_BYTE, 1, &transp_index);
+ }
+
+ delete [] and_data;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatICO::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing ICO...");
+
+ /* Image Data */
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ if (this->bpp > 8)
+ FixRGBOrder();
+
+ imBinFileWrite(handle, this->line_buffer, this->line_raw_size, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ /* AND Data */
+
+ int and_line_size = imFileLineSizeAligned(this->width, 1, 4);
+ int and_size = this->height*and_line_size;
+ imbyte* and_data = new imbyte[and_size];
+ memset(and_data, 0, and_size); /* zero = opaque */
+
+ if (imColorModeHasAlpha(this->user_color_mode))
+ {
+ imbyte* and_data_line = and_data;
+ imbyte* user_data = (imbyte*)data;
+ int depth = imColorModeDepth(this->user_color_mode);
+ int alpha_plane = depth - 1;
+
+ for (int j = 0; j < this->height; j++)
+ {
+ for (int i = 0; i < this->width; i++)
+ {
+ int offset = PixelOffset(imColorModeIsTopDown(this->user_color_mode),
+ imColorModeIsPacked(this->user_color_mode),
+ this->width, this->height, depth, i, j, alpha_plane);
+
+ if (user_data[offset] == 0) /* mark only full transparent pixels */
+ and_data_line[i / 8] |= (0x01 << (7 - (i % 8)));
+ }
+ and_data_line += and_line_size;
+ }
+ }
+ else
+ {
+ const imbyte* transp_index = (const imbyte*)AttribTable()->Get("TransparencyIndex");
+ if (imColorModeSpace(this->user_color_mode) == IM_MAP && transp_index)
+ {
+ imbyte* and_data_line = and_data;
+ imbyte* user_data = (imbyte*)data;
+ int depth = imColorModeDepth(this->user_color_mode);
+
+ for (int j = 0; j < this->height; j++)
+ {
+ for (int i = 0; i < this->width; i++)
+ {
+ int offset = PixelOffset(imColorModeIsTopDown(this->user_color_mode),
+ imColorModeIsPacked(this->user_color_mode),
+ this->width, this->height, depth, i, j, 0);
+
+ if (user_data[offset] == *transp_index)
+ and_data_line[i / 8] |= (0x01 << (7 - (i % 8)));
+ }
+ and_data_line += and_line_size;
+ }
+ }
+ }
+
+ imBinFileWrite(handle, and_data, and_size, 1);
+ delete [] and_data;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ this->image_count++;
+
+ return IM_ERR_NONE;
+}
+
+int imFormatICO::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_krn.cpp b/im/src/im_format_krn.cpp
new file mode 100755
index 0000000..a47d650
--- /dev/null
+++ b/im/src/im_format_krn.cpp
@@ -0,0 +1,325 @@
+/** \file
+ * \brief KRN - IM Kernel File Format
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_krn.cpp,v 1.3 2009/10/01 14:15:47 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <math.h>
+
+static int iKRNReadDescription(imBinFile* handle, char* comment, int *size)
+{
+ imbyte byte_value = 0;
+
+ // find the first \n
+ while(byte_value != '\n')
+ {
+ imBinFileRead(handle, &byte_value, 1, 1);
+ if (imBinFileError(handle))
+ return 0;
+ }
+
+ *size = 0;
+
+ // Read up to the next \n
+
+ imBinFileRead(handle, &byte_value, 1, 1);
+ if (imBinFileError(handle))
+ return 0;
+
+ while(byte_value != '\n')
+ {
+ if (byte_value != '\r')
+ {
+ comment[*size] = byte_value;
+ (*size)++;
+ }
+
+ imBinFileRead(handle, &byte_value, 1, 1);
+ if (imBinFileError(handle))
+ return 0;
+ }
+
+ if (*size != 0)
+ {
+ comment[*size] = 0;
+ (*size)++;
+ }
+
+ return 1;
+}
+
+static const char* iKRNCompTable[1] =
+{
+ "NONE"
+};
+
+class imFileFormatKRN: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+
+public:
+ imFileFormatKRN(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatKRN() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatKRN: public imFormat
+{
+public:
+ imFormatKRN()
+ :imFormat("KRN",
+ "IM Kernel File Format",
+ "*.krn;",
+ iKRNCompTable,
+ 1,
+ 0)
+ {}
+ ~imFormatKRN() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatKRN(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+void imFormatRegisterKRN(void)
+{
+ imFormatRegister(new imFormatKRN());
+}
+
+int imFileFormatKRN::Open(const char* file_name)
+{
+ char sig[9];
+
+ /* opens the binary file for reading */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ /* reads the KRN format identifier */
+ imBinFileRead(handle, sig, 8, 1);
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ sig[8] = 0;
+
+ if (!imStrEqual(sig, "IMKERNEL"))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ this->image_count = 1;
+ strcpy(this->compression, "NONE");
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatKRN::New(const char* file_name)
+{
+ /* opens the binary file for writing */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ this->image_count = 1;
+ if (!imBinFileWrite(handle, (void*)"IMKERNEL\n", 9, 1))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatKRN::Close()
+{
+ imBinFileClose(handle);
+}
+
+void* imFileFormatKRN::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatKRN::ReadImageInfo(int index)
+{
+ (void)index;
+ this->file_color_mode = IM_GRAY|IM_TOPDOWN;
+
+ char desc[512];
+ int desc_size;
+ if (!iKRNReadDescription(handle, desc, &desc_size))
+ return IM_ERR_ACCESS;
+
+ imAttribTable* attrib_table = AttribTable();
+ if (desc_size)
+ attrib_table->Set("Description", IM_BYTE, desc_size, desc);
+
+ if (!imBinFileReadInteger(handle, &this->width))
+ return IM_ERR_ACCESS;
+
+ if (!imBinFileReadInteger(handle, &this->height))
+ return IM_ERR_ACCESS;
+
+ int type;
+ if (!imBinFileReadInteger(handle, &type))
+ return IM_ERR_ACCESS;
+
+ if (type == 0)
+ this->file_data_type = IM_INT;
+ else
+ this->file_data_type = IM_FLOAT;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatKRN::WriteImageInfo()
+{
+ this->file_data_type = this->user_data_type;
+ this->file_color_mode = IM_GRAY|IM_TOPDOWN;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ int attrib_size;
+ const void* attrib_data = attrib_table->Get("Description", NULL, &attrib_size);
+ if (attrib_data)
+ {
+ char* desc = (char*)attrib_data;
+ int size = 0;
+ while(size < (attrib_size-1) && (desc[size] != '\r' && desc[size] != '\n'))
+ size++;
+
+ imBinFileWrite(handle, desc, size, 1);
+ }
+ imBinFileWrite(handle, (void*)"\n", 1, 1);
+
+ imBinFilePrintf(handle, "%d\n", this->width);
+ imBinFilePrintf(handle, "%d\n", this->height);
+
+ if (this->file_data_type == IM_INT)
+ imBinFileWrite(handle, (void*)"0\n", 1, 1);
+ else
+ imBinFileWrite(handle, (void*)"1\n", 1, 1);
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatKRN::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading KRN...");
+
+ for (int row = 0; row < this->height; row++)
+ {
+ for (int col = 0; col < this->width; col++)
+ {
+ if (this->file_data_type == IM_INT)
+ {
+ int value;
+ if (!imBinFileReadInteger(handle, &value))
+ return IM_ERR_ACCESS;
+
+ ((int*)this->line_buffer)[col] = value;
+ }
+ else
+ {
+ float value;
+ if (!imBinFileReadFloat(handle, &value))
+ return IM_ERR_ACCESS;
+
+ ((float*)this->line_buffer)[col] = value;
+ }
+ }
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatKRN::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing KRN...");
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ for (int col = 0; col < this->width; col++)
+ {
+ if (this->file_data_type == IM_INT)
+ {
+ int value = ((int*)this->line_buffer)[col];
+
+ if (!imBinFilePrintf(handle, "%d ", value))
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ float value = ((float*)this->line_buffer)[col];
+
+ if (!imBinFilePrintf(handle, "%f ", (double)value))
+ return IM_ERR_ACCESS;
+ }
+ }
+
+ imBinFileWrite(handle, (void*)"\n", 1, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFormatKRN::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space != IM_GRAY)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_INT && data_type != IM_FLOAT)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_led.cpp b/im/src/im_format_led.cpp
new file mode 100755
index 0000000..7b75443
--- /dev/null
+++ b/im/src/im_format_led.cpp
@@ -0,0 +1,341 @@
+/** \file
+ * \brief LED - IUP image in LED
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_led.cpp,v 1.3 2009/10/01 14:15:47 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+/* Sample LED Image
+LEDImage = IMAGE[
+0 = "0 0 0",
+1 = "192 192 192",
+2 = "0 0 128",
+3 = "255 255 255"]
+(20, 19
+,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1
+,1,1,0,3,3,3,3,0,0,1,1,1,1,1,1,1,1,1,1,1
+,1,1,0,3,3,3,3,0,3,0,1,1,1,1,1,1,1,1,1,1
+,1,1,0,3,0,0,3,0,2,2,2,2,2,2,1,1,1,1,1,1
+,1,1,0,3,3,3,3,3,2,3,3,3,3,2,2,1,1,1,1,1
+,1,1,0,3,0,0,0,0,2,3,3,3,3,2,3,2,1,1,1,1
+,1,1,0,3,3,3,3,3,2,3,0,0,3,2,2,2,2,1,1,1
+,1,1,0,3,0,0,0,0,2,3,3,3,3,3,3,3,2,1,1,1
+,1,1,0,3,3,3,3,3,2,3,0,0,0,0,0,3,2,1,1,1
+,1,1,0,0,0,0,0,0,2,3,3,3,3,3,3,3,2,1,1,1
+,1,1,1,1,1,1,1,1,2,3,0,0,0,0,0,3,2,1,1,1
+,1,1,1,1,1,1,1,1,2,3,3,3,3,3,3,3,2,1,1,1
+,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1
+,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+)
+*/
+
+static const char* iLEDCompTable[1] =
+{
+ "NONE"
+};
+
+class imFileFormatLED: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ int pal_count;
+
+ int ReadPalette();
+ int WritePalette();
+
+public:
+ imFileFormatLED(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatLED() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatLED: public imFormat
+{
+public:
+ imFormatLED()
+ :imFormat("LED",
+ "IUP image in LED special format",
+ "*.led;",
+ iLEDCompTable,
+ 1,
+ 0)
+ {}
+ ~imFormatLED() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatLED(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+
+void imFormatRegisterLED(void)
+{
+ imFormatRegister(new imFormatLED());
+}
+
+int imFileFormatLED::Open(const char* file_name)
+{
+ char sig[4];
+ unsigned char byte_value;
+ int found = 0;
+
+ /* opens the binary file for reading */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ this->image_count = 1;
+ strcpy(this->compression, "NONE");
+
+ imBinFileRead(handle, sig, 3, 1);
+ sig[3] = 0;
+
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (!imStrEqual(sig, "LED"))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ unsigned long offset = imBinFileTell(handle);
+
+ /* count the number of colors */
+ this->pal_count = -1; // will count the first '=' that is not a color
+ while (!found)
+ {
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ if (byte_value == '(')
+ found = 1;
+
+ if (byte_value == '=')
+ this->pal_count++;
+
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+ }
+
+ imBinFileSeekTo(handle, offset);
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatLED::New(const char* file_name)
+{
+ /* opens the binary file for writing */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileWrite(handle, (void*)"LEDImage = IMAGE", 16, 1);
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatLED::Close()
+{
+ imBinFileClose(handle);
+}
+
+void* imFileFormatLED::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatLED::ReadImageInfo(int index)
+{
+ (void)index;
+
+ this->palette_count = this->pal_count;
+
+ if (ReadPalette() != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ imBinFileReadInteger(handle, &this->width);
+ imBinFileReadInteger(handle, &this->height);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ this->file_data_type = IM_BYTE;
+ this->file_color_mode = IM_MAP;
+ this->file_color_mode |= IM_TOPDOWN;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatLED::WriteImageInfo()
+{
+ this->file_data_type = IM_BYTE;
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+ this->file_color_mode |= IM_TOPDOWN;
+
+ if (WritePalette() != IM_ERR_NONE)
+ return IM_ERR_ACCESS;
+
+ imBinFilePrintf(handle, "(%d, %d\n", this->width, this->height);
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatLED::ReadPalette()
+{
+ int c, r, g, b, i;
+
+ /* convert the color map to the IM format */
+ for (c = 0; c < this->palette_count; c++)
+ {
+ imBinFileReadInteger(handle, &i);
+ imBinFileReadInteger(handle, &r);
+ imBinFileReadInteger(handle, &g);
+ imBinFileReadInteger(handle, &b);
+
+ this->palette[i] = imColorEncode((unsigned char)r, (unsigned char)g, (unsigned char)b);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatLED::WritePalette()
+{
+ int c;
+ unsigned char r, g, b;
+
+ imBinFileWrite(handle, (void*)"[\n", 2, 1);
+
+ /* convert the color map from the IM format */
+ for (c = 0; c < this->palette_count; c++)
+ {
+ imColorDecode(&r, &g, &b, this->palette[c]);
+ imBinFilePrintf(handle, "%d = \"%d %d %d\"", c, (int)r, (int)g, (int)b);
+
+ if (c != this->palette_count - 1)
+ imBinFileWrite(handle, (void*)",\n", 2, 1);
+ }
+
+ imBinFileWrite(handle, (void*)"]\n", 2, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatLED::ReadImageData(void* data)
+{
+ int value;
+
+ imCounterTotal(this->counter, this->height, "Reading LED...");
+
+ for (int row = 0; row < this->height; row++)
+ {
+ for (int col = 0; col < this->width; col++)
+ {
+ if (!imBinFileReadInteger(handle, &value))
+ return IM_ERR_ACCESS;
+
+ ((imbyte*)this->line_buffer)[col] = (unsigned char)value;
+ }
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatLED::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing LED...");
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ for (int col = 0; col < this->width; col++)
+ {
+ if (!imBinFilePrintf(handle, ",%d", (int)((imbyte*)this->line_buffer)[col]))
+ return IM_ERR_ACCESS;
+ }
+
+ imBinFileWrite(handle, (void*)"\n", 1, 1);
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ imBinFileWrite(handle, (void*)")", 1, 1);
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFormatLED::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_pcx.cpp b/im/src/im_format_pcx.cpp
new file mode 100755
index 0000000..d340927
--- /dev/null
+++ b/im/src/im_format_pcx.cpp
@@ -0,0 +1,711 @@
+/** \file
+ * \brief PCX - ZSoft Picture
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_pcx.cpp,v 1.3 2009/08/19 18:39:43 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+#define PCX_ID 0x0A
+
+
+/* PCX file header */
+/* 1 Id; Manufacturer ID */
+/* 1 Version; Version */
+/* 1 Encoding; Encoding Scheme */
+/* 1 BitsPerPixel; Bits/Pixel/Plane */
+/* 2 Xmin; X Start (upper left) */
+/* 2 Ymin; Y Start (top) */
+/* 2 Xmax; X End (lower right) */
+/* 2 Ymax; Y End (bottom) */
+/* 2 Hdpi; Horizontal Resolution */
+/* 2 Vdpi; Vertical Resolution */
+/* 3*16 Colormap; 16-Color EGA Palette */
+/* 1 Reserved; Reserved */
+/* 1 NPlanes; Number of Color Planes */
+/* 2 BytesPerLine; Bytes/Line/Plane */
+/* 2 PaletteInfo; Palette Interpretation */
+/* 2 HScreenSize; Horizontal Screen Size */
+/* 2 VScreenSize; Vertical Screen Size */
+/* 54 Filler; Reserved */
+/* 128 */
+
+/* Default 16 color VGA palette */
+static unsigned char iPCXDefaultPalette[3*16] =
+{
+ 0, 0, 0,
+ 0, 0, 255,
+ 0, 255, 0,
+ 0, 255, 255,
+ 255, 0, 0,
+ 255, 0, 255,
+ 255, 255, 0,
+ 255, 255, 255,
+ 85, 85, 255,
+ 85, 85, 85,
+ 0, 170, 0,
+ 170, 0, 0,
+ 85, 255, 255,
+ 255, 85, 255,
+ 255, 255, 85,
+ 255, 255, 255
+};
+
+static int iPCXEncodeScanLine(unsigned char* EncodedBuffer, const unsigned char* DecodedBuffer, int BufferSize)
+{
+ int index = 0; /* Index into uncompressed data buffer */
+ int scanindex = 0; /* Index into compressed data buffer */
+ unsigned char runcount; /* Length of encoded pixel run */
+ unsigned char runvalue; /* Value of encoded pixel run */
+
+ while (index < BufferSize)
+ {
+ /** Get the run count of the next pixel value run.
+ ** Pixel value runs are encoded until a different pixel value
+ ** is encountered, the end of the scan line is reached, or 63
+ ** pixel values have been counted. */
+ for (runcount = 1, runvalue = DecodedBuffer[index];
+ index + runcount < BufferSize && runvalue == DecodedBuffer[index + runcount] && runcount < 63;
+ runcount++);
+
+ /** Encode the run into a one or two-unsigned char code.
+ ** Multiple pixel runs are stored in two-unsigned char codes. If a single
+ ** pixel run has a value of less than 64 then it is stored in a
+ ** one-unsigned char code. If a single pixel run has a value of 64 to 255
+ ** then it is stored in a two-unsigned char code. */
+
+ if (runcount > 1) /* Multiple pixel run */
+ {
+ EncodedBuffer[scanindex++] = (unsigned char)(runcount | 0xC0);
+ EncodedBuffer[scanindex++] = runvalue;
+ }
+ else /* Single pixel run */
+ {
+ if (DecodedBuffer[index] < 64) /* Value is 0 to 63 */
+ EncodedBuffer[scanindex++] = runvalue;
+ else /* Value is 64 to 255 */
+ {
+ EncodedBuffer[scanindex++] = (unsigned char)(runcount | 0xC0);
+ EncodedBuffer[scanindex++] = runvalue;
+ }
+ }
+
+ index += runcount; /* Jump ahead to next pixel run value */
+ }
+
+ return scanindex; /* Return the number of unsigned chars written to buffer */
+}
+
+static int iPCXDecodeScanLine(imBinFile* handle, unsigned char* DecodedBuffer, int BufferSize)
+{
+ int index = 0; /* Index into compressed scan line buffer */
+ unsigned char data; /* Data byte read from PCX file */
+ unsigned char runcount = 0; /* Length of decoded pixel run */
+ unsigned char runvalue = 0; /* Value of decoded pixel run */
+
+ while (index < BufferSize) /* Read until the end of the buffer */
+ {
+ imBinFileRead(handle, &data, 1, 1);
+
+ if ((data & 0xC0) == 0xC0) /* Two-unsigned char code */
+ {
+ runcount = (unsigned char)(data & 0x3F); /* Get run count */
+ imBinFileRead(handle, &runvalue, 1, 1);
+ }
+ else /* One unsigned char code */
+ {
+ runcount = 1; /* Run count is one */
+ runvalue = data; /* Pixel value */
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* Write the pixel run to the buffer */
+ for (;runcount && (index < BufferSize); runcount--, index++)
+ DecodedBuffer[index] = runvalue; /* Assign value to buffer */
+ }
+
+ return IM_ERR_NONE;
+}
+
+static const char* iPCXCompTable[2] =
+{
+ "NONE",
+ "RLE"
+};
+
+class imFileFormatPCX: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ int bpp; /* number of bits per pixel */
+ unsigned char version; /* format version */
+ unsigned char comp_type; /* PCX compression information */
+ int line_raw_size; /* bytes per line per plane */
+
+ int ReadPalette();
+ int WritePalette();
+ void Expand4bpp();
+ void Pack24bpp();
+ void Unpack24bpp();
+
+public:
+ imFileFormatPCX(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatPCX() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatPCX: public imFormat
+{
+public:
+ imFormatPCX()
+ :imFormat("PCX",
+ "ZSoft Picture",
+ "*.pcx;",
+ iPCXCompTable,
+ 2,
+ 0)
+ {}
+ ~imFormatPCX() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatPCX(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+
+void imFormatRegisterPCX(void)
+{
+ imFormatRegister(new imFormatPCX());
+}
+
+int imFileFormatPCX::Open(const char* file_name)
+{
+ unsigned char id;
+
+ /* opens the binary file for reading with intel unsigned char order */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ /* reads the PCX format identifier */
+ imBinFileRead(handle, &id, 1, 1);
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (id != PCX_ID)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ /* reads the format version */
+ imBinFileRead(handle, &this->version, 1, 1);
+
+ /* reads the compression comp_type */
+ imBinFileRead(handle, &this->comp_type, 1, 1);
+ if (this->comp_type)
+ strcpy(this->compression, "RLE");
+ else
+ strcpy(this->compression, "NONE");
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPCX::New(const char* file_name)
+{
+ /* opens the binary file for writing with intel byte order */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatPCX::Close()
+{
+ imBinFileClose(handle);
+}
+
+void* imFileFormatPCX::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatPCX::ReadImageInfo(int index)
+{
+ unsigned char bppp, planes;
+ unsigned short xmin, xmax, ymax, ymin, word, bplp;
+ (void)index;
+
+ this->file_data_type = IM_BYTE;
+
+ /* reads the Number of bits/pixel per plane */
+ imBinFileRead(handle, &bppp, 1, 1);
+
+ /* reads the image width and height */
+ imBinFileRead(handle, &xmin, 1, 2);
+ imBinFileRead(handle, &ymin, 1, 2);
+ imBinFileRead(handle, &xmax, 1, 2);
+ imBinFileRead(handle, &ymax, 1, 2);
+ this->width = xmax - xmin + 1;
+ this->height = ymax - ymin + 1;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ if (xmin && ymin)
+ {
+ attrib_table->Set("XScreen", IM_USHORT, 1, &xmin);
+ attrib_table->Set("YScreen", IM_USHORT, 1, &ymin);
+ }
+
+ /* read the x resolution */
+ imBinFileRead(handle, &word, 1, 2);
+ float xres = word;
+
+ /* read the y resolution */
+ imBinFileRead(handle, &word, 1, 2);
+ float yres = word;
+
+ if (xres && yres)
+ {
+ attrib_table->Set("XResolution", IM_FLOAT, 1, &xres);
+ attrib_table->Set("YResolution", IM_FLOAT, 1, &yres);
+ attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPI");
+ }
+
+ /* jump 3*16+1 bytes (colormap + reserved) */
+ imBinFileSeekOffset(handle, 3*16+1);
+
+ /* reads the Number of color planes */
+ imBinFileRead(handle, &planes, 1, 1);
+ this->bpp = bppp * planes;
+
+ /* reads the Number of bytes per scan line per color planes */
+ imBinFileRead(handle, &bplp, 1, 2);
+ this->line_raw_size = bplp * planes;
+ this->line_buffer_extra = 2; // room enough for padding
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ // sanity check
+ if (this->bpp != 1 && this->bpp != 4 &&
+ this->bpp != 8 && this->bpp != 24)
+ return IM_ERR_DATA;
+
+ if (this->bpp > 8)
+ {
+ this->file_color_mode = IM_RGB;
+ this->file_color_mode |= IM_PACKED;
+ this->line_buffer_extra += 3*this->width; // room for 24 bpp packing
+ }
+ else
+ {
+ this->file_color_mode = IM_MAP;
+ this->palette_count = 1 << this->bpp;
+
+ if (this->bpp == 1) // only 1 bpp, 4 bpp will be expanded here
+ this->convert_bpp = 1;
+
+ if (this->bpp == 4)
+ this->line_buffer_extra += this->width; // room for 4 bpp expansion
+ }
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ if (this->bpp <= 8)
+ return ReadPalette();
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPCX::WriteImageInfo()
+{
+ unsigned short word_value, bplp;
+ unsigned char byte_value, filler[54+3*2];
+
+ this->file_data_type = IM_BYTE;
+
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+
+ if (imStrEqual(this->compression, "NONE"))
+ this->comp_type = (unsigned char)0;
+ else
+ this->comp_type = (unsigned char)1;
+
+ if (this->file_color_mode == IM_BINARY)
+ {
+ this->bpp = 1;
+ this->convert_bpp = 1;
+ }
+ else if (this->file_color_mode == IM_RGB)
+ {
+ this->bpp = 24;
+ this->file_color_mode |= IM_PACKED;
+ }
+ else
+ this->bpp = 8;
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ int planes = imColorModeDepth(this->file_color_mode);
+ bplp = (unsigned short)imFileLineSizeAligned(this->width, this->bpp/planes, 2);
+ this->line_raw_size = bplp * planes;
+ this->line_buffer_extra = 2; // room enough for padding
+
+ if (this->comp_type || this->bpp == 24)
+ {
+ // allocates room for 24 bpp packing/unpacking and/or compression
+ // allocates more than enough since compression algoritm can be ineficient
+ this->line_buffer_extra += 2*this->line_raw_size;
+ }
+
+ this->version = 5;
+
+ imAttribTable* attrib_table = AttribTable();
+ /* writes the PCX file header */
+
+ unsigned short xmin = 0, ymin = 0;
+ const void* attrib_data = attrib_table->Get("XScreen");
+ if (attrib_data) xmin = *(unsigned short*)attrib_data;
+ attrib_data = attrib_table->Get("YScreen");
+ if (attrib_data) ymin = *(unsigned short*)attrib_data;
+
+ byte_value = PCX_ID;
+ imBinFileWrite(handle, &byte_value, 1, 1); /* identifier */
+ imBinFileWrite(handle, &this->version, 1, 1); /* format version */
+ imBinFileWrite(handle, &this->comp_type, 1, 1); /* compression comp_type */
+ byte_value = (imbyte)(this->bpp/planes);
+ imBinFileWrite(handle, &byte_value, 1, 1); /* bits/pixel/plane */
+ word_value = xmin;
+ imBinFileWrite(handle, &word_value, 1, 2); /* xmin */
+ word_value = ymin;
+ imBinFileWrite(handle, &word_value, 1, 2); /* ymin */
+ word_value = (unsigned short)(this->width - 1) + xmin;
+ imBinFileWrite(handle, &word_value, 1, 2); /* xmax */
+ word_value = (unsigned short)(this->height - 1) + ymin;
+ imBinFileWrite(handle, &word_value, 1, 2); /* ymax */
+
+ unsigned short hdpi = 0, vdpi = 0;
+ attrib_data = attrib_table->Get("ResolutionUnit");
+ if (attrib_data)
+ {
+ char* res_unit = (char*)attrib_data;
+
+ float* xres = (float*)attrib_table->Get("XResolution");
+ float* yres = (float*)attrib_table->Get("YResolution");
+
+ if (imStrEqual(res_unit, "DPC"))
+ {
+ hdpi = (unsigned short)(*xres * 2.54);
+ vdpi = (unsigned short)(*yres * 2.54);
+ }
+ }
+
+ /* write the x resolution */
+ word_value = hdpi;
+ imBinFileWrite(handle, &word_value, 1, 2); /* hdpi */
+
+ /* write the y resolution */
+ word_value = vdpi;
+ imBinFileWrite(handle, &word_value, 1, 2); /* vdpi */
+
+ imBinFileWrite(handle, iPCXDefaultPalette, 3*16, 1); /* 16 colors palette */
+ byte_value = 0;
+ imBinFileWrite(handle, &byte_value, 1, 1); /* reserved */
+ byte_value = (imbyte)planes;
+ imBinFileWrite(handle, &byte_value, 1, 1); /* planes */
+ word_value = bplp;
+ imBinFileWrite(handle, &word_value, 1, 2); /* bytes per line per plane */
+ memset(filler, 0, 54+3*2);
+ imBinFileWrite(handle, filler, 54+3*2, 1); /* palette info, hscreen size, vscreen size, filler */
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPCX::ReadPalette()
+{
+ unsigned char pcx_colors[256 * 3];
+
+ if (this->version == 5 && this->bpp == 1)
+ {
+ pcx_colors[0] = 0; pcx_colors[1] = 0; pcx_colors[2] = 0;
+ pcx_colors[3] = 255; pcx_colors[4] = 255; pcx_colors[5] = 255;
+ }
+ else if (this->version == 5 && this->bpp == 8)
+ {
+ unsigned char ExtPal;
+
+ /* jump to the end of file minus the palette data */
+ imBinFileSeekFrom(handle, -769);
+
+ /* reads palette identifier */
+ imBinFileRead(handle, &ExtPal, 1, 1);
+
+ if (ExtPal != 12)
+ return IM_ERR_ACCESS;
+
+ /* reads palette colors */
+ imBinFileRead(handle, pcx_colors, 768, 1);
+ }
+ else if (this->version == 3)
+ {
+ memcpy(pcx_colors, iPCXDefaultPalette, this->palette_count * 3);
+ }
+ else
+ {
+ /* jump to the begining of the file at the start of the palette data */
+ imBinFileSeekTo(handle, 4+6*2);
+
+ /* reads palette colors */
+ imBinFileRead(handle, pcx_colors, 3 * 16, 1);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * 3;
+ this->palette[c] = imColorEncode(pcx_colors[i], pcx_colors[i+1], pcx_colors[i+2]);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPCX::WritePalette()
+{
+ unsigned char ExtPal = (unsigned char)12;
+ unsigned char pcx_colors[256 * 3];
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * 3;
+ imColorDecode(&pcx_colors[i], &pcx_colors[i+1], &pcx_colors[i+2], this->palette[c]);
+ }
+
+ /* writes the palette identifier */
+ imBinFileWrite(handle, &ExtPal, 1, 1);
+
+ /* writes the color palette */
+ imBinFileWrite(handle, pcx_colors, 256 * 3, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatPCX::Expand4bpp()
+{
+ int num_bits = 8, WidthDiv8 = (this->width + 7) / 8;
+
+ int line_plane_size = this->line_raw_size / 4;
+ imbyte *in_data = (unsigned char*)this->line_buffer;
+ imbyte *out_data = in_data + this->line_buffer_size+2;
+
+ for (int x = 0; x < WidthDiv8; x++)
+ {
+ imbyte b1 = in_data[x];
+ imbyte b2 = (in_data + line_plane_size)[x];
+ imbyte b3 = (in_data + 2 * line_plane_size)[x];
+ imbyte b4 = (in_data + 3 * line_plane_size)[x];
+
+ if (x == WidthDiv8-1)
+ num_bits = this->width % 8;
+
+ for (int b = 0; b < num_bits; b++)
+ {
+ imbyte byte_value = 0;
+
+ /* If the most significant bit is set... */
+ /* Set the appropriate bit in the higher order nibble */
+ if (b1 & '\x80') byte_value |= 0x01;
+ if (b2 & '\x80') byte_value |= 0x02;
+ if (b3 & '\x80') byte_value |= 0x04;
+ if (b4 & '\x80') byte_value |= 0x08;
+ b1<<=1; b2<<=1; b3<<=1; b4<<=1;
+
+ *out_data++ = byte_value;
+ }
+ }
+
+ memcpy(this->line_buffer, in_data + this->line_buffer_size+2, this->width);
+}
+
+void imFileFormatPCX::Pack24bpp()
+{
+ imbyte *in_data = (unsigned char*)this->line_buffer;
+ imbyte *out_data = in_data + this->line_buffer_size+2;
+
+ int line_plane_size = this->line_raw_size / 3;
+
+ imbyte *red = in_data;
+ imbyte *green = in_data + line_plane_size;
+ imbyte *blue = in_data + 2*line_plane_size;
+
+ for (int i = 0; i < this->width; i++)
+ {
+ *out_data++ = *red++;
+ *out_data++ = *green++;
+ *out_data++ = *blue++;
+ }
+
+ memcpy(in_data, in_data + this->line_buffer_size+2, this->line_raw_size);
+}
+
+void imFileFormatPCX::Unpack24bpp()
+{
+ imbyte *in_data = (unsigned char*)this->line_buffer;
+ imbyte *out_data = in_data + this->line_buffer_size+2;
+
+ int line_plane_size = this->line_raw_size / 3;
+
+ imbyte *red = out_data;
+ imbyte *green = out_data + line_plane_size;
+ imbyte *blue = out_data + 2*line_plane_size;
+
+ for (int i = 0; i < this->width; i++)
+ {
+ *red++ = *in_data++;
+ *green++ = *in_data++;
+ *blue++ = *in_data++;
+ }
+
+ memcpy(out_data - (this->line_buffer_size+2), out_data, this->line_raw_size);
+}
+
+int imFileFormatPCX::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading PCX...");
+
+ imBinFileSeekTo(handle, 128);
+
+ for (int row = 0; row < this->height; row++)
+ {
+ /* read and decompress the data */
+ if (this->comp_type)
+ {
+ if (iPCXDecodeScanLine(handle, (imbyte*)this->line_buffer, this->line_raw_size) == IM_ERR_ACCESS)
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ imBinFileRead(handle, this->line_buffer, this->line_raw_size, 1);
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+
+ if (this->bpp == 4)
+ Expand4bpp();
+
+ if (this->bpp == 24)
+ Pack24bpp();
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPCX::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing PCX...");
+
+ imBinFileSeekTo(handle, 128);
+
+ imbyte* compressed_buffer = NULL;
+ if (this->comp_type) // point to the extra buffer
+ compressed_buffer = (imbyte*)this->line_buffer + this->line_buffer_size+2;
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ if (this->bpp == 24)
+ Unpack24bpp();
+
+ /* compress and writes the data */
+ /* the compressed buffer size will probably be diferent from the uncompressed buffer size */
+ if (this->comp_type)
+ {
+ int compressed_size = iPCXEncodeScanLine(compressed_buffer, (imbyte*)this->line_buffer, this->line_raw_size);
+ imBinFileWrite(handle, compressed_buffer, compressed_size, 1);
+ }
+ else
+ {
+ imBinFileWrite(handle, this->line_buffer, this->line_raw_size, 1);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ if (this->bpp == 8)
+ return WritePalette();
+
+ return IM_ERR_NONE;
+}
+
+int imFormatPCX::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE") && !imStrEqual(compression, "RLE"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_pnm.cpp b/im/src/im_format_pnm.cpp
new file mode 100755
index 0000000..9347ddc
--- /dev/null
+++ b/im/src/im_format_pnm.cpp
@@ -0,0 +1,483 @@
+/** \file
+ * \brief PNM - Netpbm Portable Image Map
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_pnm.cpp,v 1.3 2009/10/01 14:15:47 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+
+/* comments start with '#' after the first \n */
+static int iPNMReadComment(imBinFile* handle, char* comment, int *size)
+{
+ imbyte byte_value = 0;
+
+ // find the first \n
+ while(byte_value != '\n')
+ {
+ imBinFileRead(handle, &byte_value, 1, 1);
+ if (imBinFileError(handle))
+ return 0;
+ }
+
+ *size = 0;
+
+ imBinFileRead(handle, &byte_value, 1, 1);
+ if (imBinFileError(handle))
+ return 0;
+
+ if (byte_value == '#')
+ {
+ while(byte_value != '\n')
+ {
+ imBinFileRead(handle, &byte_value, 1, 1);
+ if (imBinFileError(handle))
+ return 0;
+
+ if (byte_value != '\r')
+ {
+ comment[*size] = byte_value;
+ (*size)++;
+ }
+ }
+ }
+ else
+ imBinFileSeekOffset(handle, -1);
+
+ if (*size != 0)
+ {
+ comment[*size] = 0;
+ (*size)++;
+ }
+
+ return 1;
+}
+
+static const char* iPNMCompTable[2] =
+{
+ "NONE",
+ "ASCII"
+};
+
+class imFileFormatPNM: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ unsigned char image_type;
+
+ void FixBinary();
+
+public:
+ imFileFormatPNM(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatPNM() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatPNM: public imFormat
+{
+public:
+ imFormatPNM()
+ :imFormat("PNM",
+ "Netpbm Portable Image Map",
+ "*.pnm;*.pbm;*.ppm;*.pgm;",
+ iPNMCompTable,
+ 2,
+ 1)
+ {}
+ ~imFormatPNM() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatPNM(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+
+void imFormatRegisterPNM(void)
+{
+ imFormatRegister(new imFormatPNM());
+}
+
+int imFileFormatPNM::Open(const char* file_name)
+{
+ unsigned char sig[2];
+
+ /* opens the binary file for reading */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ /* reads the PNM format identifier */
+ imBinFileRead(handle, sig, 2, 1);
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (sig[0] != 'P' || (sig[1] != '1' && sig[1] != '2' &&
+ sig[1] != '3' && sig[1] != '4' &&
+ sig[1] != '5' && sig[1] != '6'))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ this->image_type = sig[1];
+ this->image_count = 1; // increment this if found image after data
+
+ if (this->image_type == '1' || this->image_type == '2' || this->image_type == '3')
+ strcpy(this->compression, "ASCII");
+ else
+ strcpy(this->compression, "NONE");
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPNM::New(const char* file_name)
+{
+ /* opens the binary file for writing */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatPNM::Close()
+{
+ imBinFileClose(handle);
+}
+
+void* imFileFormatPNM::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatPNM::ReadImageInfo(int index)
+{
+ (void)index;
+
+ switch (this->image_type)
+ {
+ case '4':
+ this->convert_bpp = 1;
+ case '1':
+ this->file_color_mode = IM_BINARY;
+ break;
+ case '2':
+ case '5':
+ this->file_color_mode = IM_GRAY;
+ break;
+ case '3':
+ case '6':
+ this->file_color_mode = IM_RGB | IM_PACKED;
+ break;
+ }
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ char comment[4096];
+ int size;
+ if (!iPNMReadComment(handle, comment, &size))
+ return IM_ERR_ACCESS;
+
+ if (size)
+ attrib_table->Set("Description", IM_BYTE, size, comment);
+
+ if (!imBinFileReadInteger(handle, &this->width))
+ return IM_ERR_ACCESS;
+
+ if (!imBinFileReadInteger(handle, &this->height))
+ return IM_ERR_ACCESS;
+
+ if (this->height <= 0 || this->width <= 0)
+ return IM_ERR_DATA;
+
+ int max_val = 255;
+ if (this->image_type != '4' && this->image_type != '1')
+ {
+ if (!imBinFileReadInteger(handle, &max_val))
+ return IM_ERR_ACCESS;
+ }
+
+ this->file_data_type = IM_BYTE;
+ if (max_val > 255)
+ this->file_data_type = IM_USHORT;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPNM::WriteImageInfo()
+{
+ this->file_data_type = this->user_data_type;
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+
+ int ascii;
+ if (imStrEqual(this->compression, "ASCII"))
+ ascii = 1;
+ else
+ ascii = 0;
+
+ switch (this->file_color_mode)
+ {
+ case IM_BINARY:
+ if (ascii)
+ this->image_type = '1';
+ else
+ {
+ this->image_type = '4';
+ this->convert_bpp = 1;
+ }
+ break;
+ case IM_GRAY:
+ if (ascii)
+ this->image_type = '2';
+ else
+ this->image_type = '5';
+ break;
+ case IM_RGB:
+ if (ascii)
+ this->image_type = '3';
+ else
+ this->image_type = '6';
+ this->file_color_mode |= IM_PACKED;
+ break;
+ }
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ imBinFilePrintf(handle, "P%c\n", (int)this->image_type);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ int attrib_size;
+ const void* attrib_data = attrib_table->Get("Description", NULL, &attrib_size);
+ if (attrib_data)
+ {
+ char* desc = (char*)attrib_data;
+ int size = 0;
+ while(size < (attrib_size-1) && (desc[size] != '\r' && desc[size] != '\n'))
+ size++;
+
+ imBinFileWrite(handle, (void*)"#", 1, 1);
+ imBinFileWrite(handle, desc, size, 1);
+ imBinFileWrite(handle, (void*)"\n", 1, 1);
+ }
+
+ imBinFilePrintf(handle, "%d\n", this->width);
+ imBinFilePrintf(handle, "%d\n", this->height);
+
+ if (this->image_type != '4' && this->image_type != '1')
+ {
+ int max_val = 255;
+ if (this->file_data_type == IM_USHORT)
+ max_val = 65535;
+
+ imBinFilePrintf(handle, "%d\n", max_val);
+ }
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatPNM::FixBinary()
+{
+ unsigned char* buf = (unsigned char*)this->line_buffer;
+ for (int b = 0; b < this->line_buffer_size; b++)
+ {
+ *buf = ~(*buf);
+ buf++;
+ }
+}
+
+int imFileFormatPNM::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading PNM...");
+
+ int line_count = imImageLineCount(this->width, this->file_color_mode);
+
+ int line_raw_size;
+ if (this->image_type == '4')
+ line_raw_size = imFileLineSizeAligned(this->width, 1, 1);
+ else
+ line_raw_size = imImageLineSize(this->width, this->file_color_mode, this->file_data_type);
+
+ int ascii = 0;
+ if (this->image_type == '1' || this->image_type == '2' || this->image_type == '3')
+ ascii = 1;
+
+ for (int row = 0; row < this->height; row++)
+ {
+ if (ascii)
+ {
+ int value;
+ for (int col = 0; col < line_count; col++)
+ {
+ if (!imBinFileReadInteger(handle, &value))
+ return IM_ERR_ACCESS;
+
+ if (this->image_type == '1' && value < 2)
+ value = 1 - value;
+
+ if (this->file_data_type == IM_USHORT)
+ ((imushort*)this->line_buffer)[col] = (imushort)value;
+ else
+ ((imbyte*)this->line_buffer)[col] = (unsigned char)value;
+ }
+ }
+ else
+ {
+ imBinFileRead(handle, this->line_buffer, line_raw_size, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->image_type == '4')
+ FixBinary();
+ }
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ // try to find another image, ignore errors from here
+
+ /* reads the PNM format identifier */
+ unsigned char sig[2];
+ imBinFileRead(handle, sig, 2, 1);
+ if (imBinFileError(handle))
+ return IM_ERR_NONE;
+
+ if (sig[0] != 'P' || (sig[1] != '1' && sig[1] != '2' &&
+ sig[1] != '3' && sig[1] != '4' &&
+ sig[1] != '5' && sig[1] != '6'))
+ return IM_ERR_NONE;
+
+ this->image_type = sig[1];
+ this->image_count++;
+
+ if (this->image_type == '1' || this->image_type == '2' || this->image_type == '3')
+ strcpy(this->compression, "ASCII");
+ else
+ strcpy(this->compression, "NONE");
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatPNM::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing PNM...");
+
+ int line_count = imImageLineCount(this->width, this->file_color_mode);
+
+ int line_raw_size;
+ if (this->image_type == '4')
+ line_raw_size = imFileLineSizeAligned(this->width, 1, 1);
+ else
+ line_raw_size = imImageLineSize(this->width, this->file_color_mode, this->file_data_type);
+
+ int ascii = 0;
+ if (this->image_type == '1' || this->image_type == '2' || this->image_type == '3')
+ ascii = 1;
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ if (ascii)
+ {
+ int line_size = 0;
+ for (int col = 0; col < line_count; col++)
+ {
+ int value;
+ if (this->file_data_type == IM_USHORT)
+ value = ((imushort*)this->line_buffer)[col];
+ else
+ value = ((imbyte*)this->line_buffer)[col];
+
+ if (this->image_type == '1' && value < 2)
+ value = 1 - value;
+
+ int write_size = imBinFilePrintf(handle, "%d ", value);
+ if (!write_size)
+ return IM_ERR_ACCESS;
+
+ line_size += write_size;
+
+ // No line should be longer than 70 characters.
+ if (line_size > 60 || col == line_count-1)
+ {
+ line_size = 0;
+ imBinFileWrite(handle, (void*)"\n", 1, 1);
+ }
+ }
+ }
+ else
+ {
+ if (this->image_type == '4')
+ FixBinary();
+
+ imBinFileWrite(handle, this->line_buffer, line_raw_size, 1);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFormatPNM::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK || color_space == IM_MAP)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE && data_type != IM_USHORT)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE") && !imStrEqual(compression, "ASCII"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_ras.cpp b/im/src/im_format_ras.cpp
new file mode 100755
index 0000000..1960c49
--- /dev/null
+++ b/im/src/im_format_ras.cpp
@@ -0,0 +1,608 @@
+/** \file
+ * \brief RAS - Sun Raster File
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_ras.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_format_all.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+/* File Header Structure. */
+/* 4 Magic; magic number */
+/* 4 BufferSize; width (pixels) of image */
+/* 4 Height; height (pixels) of image */
+/* 4 Depth; depth (1, 8, 24, or 32) of pixel */
+/* 4 Length; length (bytes) of image */
+/* 4 Type; type of file; see RT_OLD below */
+/* 4 MapType; type of colormap; see RAS_NONE below */
+/* 4 MapLength; length (bytes) of following map */
+/* 32 */
+
+#define RAS_ID 0x59A66A95
+
+/* Sun supported ras_type's */
+#define RAS_OLD 0 /* Raw pixrect image in 68000 byte order */
+#define RAS_STANDARD 1 /* Raw pixrect image in 68000 byte order */
+#define RAS_BYTE_ENCODED 2 /* Run-length compression of bytes */
+#define RAS_EXPERIMENTAL 0xffff /* Reserved for testing */
+
+#define RAS_ESCAPE 0x80
+
+/* Sun supported ras_maptype's */
+#define RAS_NONE 0 /* ras_maplength is expected to be 0 */
+#define RAS_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */
+#define RAS_RAW 2 /* Sun registered ras_maptype's */
+
+
+/* NOTES:
+ * Each line of the image is rounded out to a multiple of 16 bits.
+ * This corresponds to the rounding convention used by the memory pixrect
+ * package (/usr/include/pixrect/memvar.h) of the SunWindows system.
+ * The ras_encoding field (always set to 0 by Sun's supported software)
+ * was renamed to ras_length in release 2.0. As a result, rasterfiles
+ * of type 0 generated by the old software claim to have 0 length; for
+ * compatibility, code reading rasterfiles must be prepared to compute the
+ * true length from the width, height, and depth fields. */
+
+static int iRASDecodeScanLine(imBinFile* handle, unsigned char* DecodedBuffer, int BufferSize)
+{
+ int index = 0;
+ unsigned char count = 0;
+ unsigned char value = 0;
+
+ while (index < BufferSize)
+ {
+ imBinFileRead(handle, &value, 1, 1);
+
+ if (value == RAS_ESCAPE)
+ {
+ imBinFileRead(handle, &count, 1, 1);
+
+ if (count != 0)
+ {
+ imBinFileRead(handle, &value, 1, 1);
+
+ count++;
+ while (count-- && index < BufferSize)
+ {
+ *DecodedBuffer++ = value;
+ index++;
+ }
+ }
+ else
+ {
+ *DecodedBuffer++ = RAS_ESCAPE;
+ index++;
+ }
+ }
+ else
+ {
+ *DecodedBuffer++ = value;
+ index++;
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+static int iRASEncodeScanLine(imbyte* EncodedBuffer, const imbyte* DecodedBuffer, int BufferSize)
+{
+ int index = 0; /* Index into uncompressed data buffer */
+ int scanindex = 0; /* Index into compressed data buffer */
+ int runcount; /* Length of encoded pixel run */
+ unsigned char runvalue; /* Value of encoded pixel run */
+
+ while (index < BufferSize)
+ {
+ for (runcount = 1, runvalue = DecodedBuffer[index];
+ index + runcount < BufferSize && runvalue == DecodedBuffer[index + runcount] && runcount < 256;
+ runcount++);
+
+ if (runcount > 2) /* Multiple pixel run */
+ {
+ EncodedBuffer[scanindex++] = RAS_ESCAPE;
+ EncodedBuffer[scanindex++] = (imbyte)(runcount-1);
+ EncodedBuffer[scanindex++] = runvalue;
+ }
+ else if (runcount == 2)
+ {
+ if (runvalue == RAS_ESCAPE) /* Two Escapes */
+ {
+ EncodedBuffer[scanindex++] = RAS_ESCAPE;
+ EncodedBuffer[scanindex++] = 1;
+ EncodedBuffer[scanindex++] = RAS_ESCAPE;
+ }
+ else /* Two Single runs */
+ {
+ EncodedBuffer[scanindex++] = runvalue;
+ EncodedBuffer[scanindex++] = runvalue;
+ }
+ }
+ else /* Single run */
+ {
+ if (runvalue == RAS_ESCAPE)
+ {
+ EncodedBuffer[scanindex++] = RAS_ESCAPE;
+ EncodedBuffer[scanindex++] = 0;
+ }
+ else
+ EncodedBuffer[scanindex++] = runvalue;
+ }
+
+ index += runcount; /* Jump ahead to next pixel run value */
+ }
+
+ return scanindex; /* Return the number of unsigned chars written to buffer */
+}
+
+static const char* iRASCompTable[2] =
+{
+ "NONE",
+ "RLE"
+};
+
+class imFileFormatRAS: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ unsigned int bpp, /* number of bits per pixel */
+ comp_type, /* ras compression information */
+ map_type, /* palette information */
+ line_raw_size; /* line buffer size */
+
+ int ReadPalette();
+ int WritePalette();
+ void FixRGB();
+
+public:
+ imFileFormatRAS(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatRAS() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatRAS: public imFormat
+{
+public:
+ imFormatRAS()
+ :imFormat("RAS",
+ "Sun Raster File",
+ "*.ras;",
+ iRASCompTable,
+ 2,
+ 0)
+ {}
+ ~imFormatRAS() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatRAS(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+
+void imFormatRegisterRAS(void)
+{
+ imFormatRegister(new imFormatRAS());
+}
+
+int imFileFormatRAS::Open(const char* file_name)
+{
+ unsigned int dword_value;
+
+ /* opens the binary file for reading with motorola byte order */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_BIGENDIAN);
+
+ /* reads the RAS format identifier */
+ imBinFileRead(handle, &dword_value, 1, 4);
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (dword_value != RAS_ID)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ /* reads the compression information */
+ imBinFileSeekOffset(handle, 16);
+
+ imBinFileRead(handle, &this->comp_type, 1, 4);
+ if (this->comp_type == RAS_BYTE_ENCODED)
+ strcpy(this->compression, "RLE");
+ else if (this->comp_type == RAS_OLD || this->comp_type == RAS_STANDARD)
+ strcpy(this->compression, "NONE");
+ else
+ {
+ imBinFileClose(handle);
+ return IM_ERR_COMPRESS;
+ }
+
+ imBinFileSeekOffset(handle, -20);
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAS::New(const char* file_name)
+{
+ /* opens the binary file for writing with motorola byte order */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_BIGENDIAN);
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatRAS::Close()
+{
+ imBinFileClose(handle);
+}
+
+void* imFileFormatRAS::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatRAS::ReadImageInfo(int index)
+{
+ (void)index;
+ unsigned int dword_value;
+
+ this->file_data_type = IM_BYTE;
+
+ /* reads the image width */
+ imBinFileRead(handle, &dword_value, 1, 4);
+ this->width = (int)dword_value;
+
+ /* reads the image height */
+ imBinFileRead(handle, &dword_value, 1, 4);
+ this->height = (int)dword_value;
+
+ /* reads the number of bits per pixel */
+ imBinFileRead(handle, &this->bpp, 1, 4);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ // sanity check
+ if (this->bpp != 1 && this->bpp != 8 &&
+ this->bpp != 24 && this->bpp != 32)
+ return IM_ERR_DATA;
+
+ if (this->bpp > 8)
+ {
+ this->file_color_mode = IM_RGB;
+ this->file_color_mode |= IM_PACKED;
+
+ if (this->bpp == 32)
+ this->file_color_mode |= IM_ALPHA;
+ }
+ else
+ {
+ this->file_color_mode = IM_MAP;
+
+ if (this->bpp == 1)
+ {
+ this->convert_bpp = 1;
+ this->palette_count = 2;
+ }
+ }
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 2);
+ this->line_buffer_extra = 2; // room enough for padding
+
+ /* jump 8 bytes (Length+Compression) */
+ imBinFileSeekOffset(handle, 8);
+
+ /* reads the palette information */
+ imBinFileRead(handle, &this->map_type, 1, 4);
+
+ /* reads the palette size */
+ imBinFileRead(handle, &dword_value, 1, 4);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* updates the pal_size based on the palette size */
+ if (this->bpp <= 8 && this->map_type != RAS_NONE)
+ {
+ this->palette_count = dword_value / 3;
+ return ReadPalette();
+ }
+
+ if (this->bpp <= 8 && this->map_type == RAS_NONE)
+ {
+ if (this->bpp == 1)
+ this->file_color_mode = IM_BINARY;
+ else
+ this->file_color_mode = IM_GRAY;
+
+ this->file_color_mode |= IM_TOPDOWN;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAS::WriteImageInfo()
+{
+ this->file_data_type = IM_BYTE;
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+
+ if (imStrEqual(this->compression, "RLE"))
+ this->comp_type = RAS_BYTE_ENCODED;
+ else
+ this->comp_type = RAS_STANDARD;
+
+ // Force the palette, even for Binary and Gray.
+ this->map_type = RAS_EQUAL_RGB;
+
+ if (this->file_color_mode == IM_BINARY)
+ {
+ this->bpp = 1;
+ this->convert_bpp = 1;
+ }
+ else if (this->file_color_mode == IM_RGB)
+ {
+ this->file_color_mode |= IM_PACKED;
+ this->map_type = RAS_NONE;
+ this->bpp = 24;
+
+ if (imColorModeHasAlpha(this->user_color_mode))
+ {
+ this->file_color_mode |= IM_ALPHA;
+ this->bpp = 32;
+ }
+ }
+ else
+ this->bpp = 8;
+
+ this->file_color_mode |= IM_TOPDOWN;
+
+ this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 2);
+ this->line_buffer_extra = 2; // room enough for padding
+
+ if (this->comp_type == RAS_BYTE_ENCODED)
+ {
+ // allocates more than enough since compression algoritm can be ineficient
+ this->line_buffer_extra += 2*this->line_raw_size;
+ }
+
+ /* writes the RAS file header */
+
+ unsigned int dword_value = RAS_ID;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* identifier */
+ dword_value = this->width;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* image width */
+ dword_value = this->height;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* image height */
+ dword_value = this->bpp;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* bits per pixel */
+ dword_value = this->height * this->line_raw_size;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* image lenght */
+ dword_value = this->comp_type;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* compression information */
+ dword_value = this->map_type;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* palette information */
+ dword_value = (this->map_type == RAS_NONE)? 0: this->palette_count * 3;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* palette lenght */
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->map_type != RAS_NONE)
+ return WritePalette();
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAS::ReadPalette()
+{
+ unsigned char ras_colors[256 * 3];
+
+ /* reads the color palette */
+ imBinFileRead(handle, ras_colors, this->palette_count * 3, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ if (this->map_type == RAS_RAW)
+ {
+ int i = c * 3;
+ this->palette[c] = imColorEncode(ras_colors[i],
+ ras_colors[i+1],
+ ras_colors[i+2]);
+ }
+ else
+ {
+ this->palette[c] = imColorEncode(ras_colors[c],
+ ras_colors[c+this->palette_count],
+ ras_colors[c+2*this->palette_count]);
+ }
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAS::WritePalette()
+{
+ int c;
+ unsigned char ras_colors[256 * 3];
+
+ /* convert the color map to the IM format */
+ for (c = 0; c < this->palette_count; c++)
+ {
+ imColorDecode(&ras_colors[c], &ras_colors[c+this->palette_count], &ras_colors[c+2*this->palette_count], this->palette[c]);
+ }
+
+ /* writes the color palette */
+ imBinFileWrite(handle, ras_colors, this->palette_count * 3, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatRAS::FixRGB()
+{
+ int x;
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+
+ switch (this->bpp)
+ {
+ case 32:
+ {
+ // convert ABGR <-> RGBA
+ for (x = 0; x < this->width; x++)
+ {
+ int c = x*4;
+ imbyte temp = byte_data[c]; // swap R and A
+ byte_data[c] = byte_data[c+3];
+ byte_data[c+3] = temp;
+
+ temp = byte_data[c+1]; // swap G and B
+ byte_data[c+1] = byte_data[c+2];
+ byte_data[c+2] = temp;
+ }
+ }
+ break;
+ default: // 24
+ {
+ // convert BGR <-> RGB
+ for (x = 0; x < this->width; x++)
+ {
+ int c = x*3;
+ imbyte temp = byte_data[c]; // swap R and B
+ byte_data[c] = byte_data[c+2];
+ byte_data[c+2] = temp;
+ }
+ }
+ break;
+ }
+}
+
+int imFileFormatRAS::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading RAS...");
+
+ for (int row = 0; row < this->height; row++)
+ {
+ /* read and decompress the data */
+ if (this->comp_type != RAS_BYTE_ENCODED)
+ {
+ imBinFileRead(handle, this->line_buffer, this->line_raw_size, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ if (iRASDecodeScanLine(handle, (imbyte*)this->line_buffer, this->line_raw_size) == IM_ERR_ACCESS)
+ return IM_ERR_ACCESS;
+ }
+
+ if (this->bpp > 8)
+ FixRGB();
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAS::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing RAS...");
+
+ imbyte* compressed_buffer = NULL;
+ if (this->comp_type == RAS_BYTE_ENCODED) // point to the extra buffer
+ compressed_buffer = (imbyte*)this->line_buffer + this->line_buffer_size+2;
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ if (this->bpp > 8)
+ FixRGB();
+
+ if (this->comp_type == RAS_BYTE_ENCODED)
+ {
+ int compressed_size = iRASEncodeScanLine(compressed_buffer, (imbyte*)this->line_buffer, this->line_raw_size);
+ imBinFileWrite(handle, compressed_buffer, compressed_size, 1);
+ }
+ else
+ {
+ imBinFileWrite(handle, this->line_buffer, this->line_raw_size, 1);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFormatRAS::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE") && !imStrEqual(compression, "RLE"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_raw.cpp b/im/src/im_format_raw.cpp
new file mode 100755
index 0000000..56a2096
--- /dev/null
+++ b/im/src/im_format_raw.cpp
@@ -0,0 +1,366 @@
+/** \file
+ * \brief RAW File Format
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_raw.cpp,v 1.5 2009/10/01 14:15:47 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_util.h"
+#include "im_format_raw.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+static const char* iRAWCompTable[2] =
+{
+ "NONE",
+ "ASCII"
+};
+
+class imFileFormatRAW: public imFileFormatBase
+{
+ imBinFile* handle;
+ int padding;
+
+ int iRawUpdateParam(int index);
+
+public:
+ imFileFormatRAW(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatRAW() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatRAW: public imFormat
+{
+public:
+ imFormatRAW()
+ :imFormat("RAW",
+ "RAW File Format",
+ "*.*;",
+ iRAWCompTable,
+ 2,
+ 1)
+ {}
+ ~imFormatRAW() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatRAW(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+static imFormat* raw_format = NULL;
+
+void imFormatFinishRAW(void)
+{
+ if (raw_format)
+ {
+ delete raw_format;
+ raw_format = NULL;
+ }
+}
+
+imFormat* imFormatInitRAW(void)
+{
+ if (!raw_format)
+ raw_format = new imFormatRAW();
+
+ return raw_format;
+}
+
+int imFileFormatRAW::Open(const char* file_name)
+{
+ this->handle = imBinFileOpen(file_name);
+ if (this->handle == NULL)
+ return IM_ERR_OPEN;
+
+ strcpy(this->compression, "NONE");
+
+ this->image_count = 1; /* at least one image */
+ this->padding = 0;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAW::New(const char* file_name)
+{
+ this->handle = imBinFileNew(file_name);
+ if (this->handle == NULL)
+ return IM_ERR_OPEN;
+
+ this->padding = 0;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatRAW::Close()
+{
+ imBinFileClose(this->handle);
+}
+
+void* imFileFormatRAW::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+static int iCalcPad(int padding, int line_size)
+{
+ if (padding == 1)
+ return 0;
+
+ {
+ int rest = line_size % padding;
+ if (rest == 0)
+ return 0;
+
+ return padding - rest;
+ }
+}
+
+int imFileFormatRAW::iRawUpdateParam(int index)
+{
+ (void)index;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ // update image count
+ int* icount = (int*)attrib_table->Get("ImageCount");
+ if (icount)
+ this->image_count = *icount;
+ else
+ this->image_count = 1;
+
+ // update file byte order
+ int* byte_order = (int*)attrib_table->Get("ByteOrder");
+ if (byte_order)
+ imBinFileByteOrder(this->handle, *byte_order);
+
+ // position at start offset, the default is at 0
+ int* start_offset = (int*)attrib_table->Get("StartOffset");
+ if (!start_offset)
+ imBinFileSeekOffset(this->handle, 0);
+ else
+ imBinFileSeekOffset(this->handle, *start_offset);
+
+ if (imBinFileError(this->handle))
+ return IM_ERR_ACCESS;
+
+ int* stype = (int*)attrib_table->Get("SwitchType");
+ if (stype)
+ this->switch_type = *stype;
+
+ // The following attributes MUST exist
+ this->width = *(int*)attrib_table->Get("Width");
+ this->height = *(int*)attrib_table->Get("Height");
+ this->file_color_mode = *(int*)attrib_table->Get("ColorMode");
+ this->file_data_type = *(int*)attrib_table->Get("DataType");
+
+ int* pad = (int*)attrib_table->Get("Padding");
+ if (pad)
+ {
+ int line_size = imImageLineSize(this->width, this->file_color_mode, this->file_data_type);
+ if (this->switch_type && (this->file_data_type == IM_FLOAT || this->file_data_type == IM_CFLOAT))
+ line_size *= 2;
+ this->padding = iCalcPad(*pad, line_size);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAW::ReadImageInfo(int index)
+{
+ return iRawUpdateParam(index);
+}
+
+int imFileFormatRAW::WriteImageInfo()
+{
+ this->file_color_mode = this->user_color_mode;
+ this->file_data_type = this->user_data_type;
+
+ return iRawUpdateParam(this->image_count);
+}
+
+static int iFileDataTypeSize(int file_data_type, int switch_type)
+{
+ int type_size = imDataTypeSize(file_data_type);
+ if ((file_data_type == IM_FLOAT || file_data_type == IM_CFLOAT) && switch_type)
+ type_size *= 2;
+ return type_size;
+}
+
+int imFileFormatRAW::ReadImageData(void* data)
+{
+ int count = imFileLineBufferCount(this);
+ int line_count = imImageLineCount(this->width, this->file_color_mode);
+ int type_size = iFileDataTypeSize(this->file_data_type, this->switch_type);
+
+ // treat complex as 2 real
+ if (this->file_data_type == IM_CFLOAT)
+ {
+ type_size /= 2;
+ line_count *= 2;
+ }
+
+ int ascii;
+ if (imStrEqual(this->compression, "ASCII"))
+ ascii = 1;
+ else
+ ascii = 0;
+
+ imCounterTotal(this->counter, count, "Reading RAW...");
+
+ int row = 0, plane = 0;
+ for (int i = 0; i < count; i++)
+ {
+ if (ascii)
+ {
+ for (int col = 0; col < line_count; col++)
+ {
+ if (this->file_data_type == IM_FLOAT)
+ {
+ float value;
+ if (!imBinFileReadFloat(handle, &value))
+ return IM_ERR_ACCESS;
+
+ ((float*)this->line_buffer)[col] = value;
+ }
+ else
+ {
+ int value;
+ if (!imBinFileReadInteger(handle, &value))
+ return IM_ERR_ACCESS;
+
+ if (this->file_data_type == IM_INT)
+ ((int*)this->line_buffer)[col] = value;
+ else if (this->file_data_type == IM_USHORT)
+ ((imushort*)this->line_buffer)[col] = (imushort)value;
+ else
+ ((imbyte*)this->line_buffer)[col] = (unsigned char)value;
+ }
+ }
+ }
+ else
+ {
+ imBinFileRead(this->handle, (imbyte*)this->line_buffer, line_count, type_size);
+
+ if (imBinFileError(this->handle))
+ return IM_ERR_ACCESS;
+ }
+
+ imFileLineBufferRead(this, data, row, plane);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+
+ imFileLineBufferInc(this, &row, &plane);
+
+ if (this->padding)
+ imBinFileSeekOffset(this->handle, this->padding);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatRAW::WriteImageData(void* data)
+{
+ int count = imFileLineBufferCount(this);
+ int line_count = imImageLineCount(this->width, this->file_color_mode);
+ int type_size = iFileDataTypeSize(this->file_data_type, this->switch_type);
+
+ // treat complex as 2 real
+ if (this->file_data_type == IM_CFLOAT)
+ {
+ type_size /= 2;
+ line_count *= 2;
+ }
+
+ int ascii;
+ if (imStrEqual(this->compression, "ASCII"))
+ ascii = 1;
+ else
+ ascii = 0;
+
+ imCounterTotal(this->counter, count, "Writing RAW...");
+
+ int row = 0, plane = 0;
+ for (int i = 0; i < count; i++)
+ {
+ imFileLineBufferWrite(this, data, row, plane);
+
+ if (ascii)
+ {
+ for (int col = 0; col < line_count; col++)
+ {
+ if (this->file_data_type == IM_FLOAT)
+ {
+ float value = ((float*)this->line_buffer)[col];
+
+ if (!imBinFilePrintf(handle, "%f ", (double)value))
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ int value;
+ if (this->file_data_type == IM_INT)
+ value = ((int*)this->line_buffer)[col];
+ else if (this->file_data_type == IM_USHORT)
+ value = ((imushort*)this->line_buffer)[col];
+ else
+ value = ((imbyte*)this->line_buffer)[col];
+
+ if (!imBinFilePrintf(handle, "%d ", value))
+ return IM_ERR_ACCESS;
+ }
+ }
+
+ imBinFileWrite(handle, (void*)"\n", 1, 1);
+ }
+ else
+ {
+ imBinFileWrite(this->handle, (imbyte*)this->line_buffer, line_count, type_size);
+ }
+
+ if (imBinFileError(this->handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+
+ imFileLineBufferInc(this, &row, &plane);
+
+ if (this->padding)
+ imBinFileSeekOffset(this->handle, this->padding);
+ }
+
+ this->image_count++;
+ return IM_ERR_NONE;
+}
+
+int imFormatRAW::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ (void)data_type;
+
+ if (imColorSpace(color_mode) == IM_MAP)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE") && !imStrEqual(compression, "ASCII"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_sgi.cpp b/im/src/im_format_sgi.cpp
new file mode 100755
index 0000000..08bbf4d
--- /dev/null
+++ b/im/src/im_format_sgi.cpp
@@ -0,0 +1,616 @@
+/** \file
+ * \brief SGI - Silicon Graphics Image File Format
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_sgi.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_util.h"
+#include "im_format_all.h"
+#include "im_counter.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+/* File Header Structure. */
+/* 2 Magic; 474 */
+/* 1 Storage; 0 ou 1 Compression */
+/* 1 BPC; 1 ou 2 Bytes Per Pixel Component */
+/* 2 Dimension; 1 ou 2 ou 3 */
+/* 2 XSize; Width */
+/* 2 YSize; Height */
+/* 2 ZSize; Number of Channels. B/W=1, RGB=3, RGBA=4 */
+/* 4 PixMin; Minimum Pixel Value */
+/* 4 PixMax; Maximum Pixel Value */
+/* 4 Dummy1; */
+/* 80 ImageName;*/
+/* 4 ColorMap; 0 ou 1 ou 2 ou 3 */
+/* 404 Dummy2;*/
+/* 512 */
+
+#define SGI_ID 474
+
+/* Compression */
+#define SGI_VERBATIM 0
+#define SGI_RLE 1
+
+/* ColorMap Ids */
+#define SGI_NORMAL 0
+#define SGI_DITHERED 1
+#define SGI_SCREEN 2
+#define SGI_COLORMAP 3
+
+template <class T>
+static int iSGIDecodeScanLine(T *optr, const T *iptr, int width)
+{
+ T pixel;
+ int c = 0, count;
+
+ while (c < width)
+ {
+ pixel = *iptr++;
+
+ count = pixel & 0x7f;
+ if (!count)
+ break;
+
+ c += count;
+ if (c > width)
+ return IM_ERR_ACCESS;
+
+ if (pixel & 0x80)
+ {
+ while (count--)
+ *optr++ = *iptr++;
+ }
+ else
+ {
+ pixel = *iptr++;
+ while (count--)
+ *optr++ = pixel;
+ }
+ }
+
+ if (c < width)
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+template <class T>
+static int iSGIEncodeScanLine(T *optr, const T *iptr, int width)
+{
+ const T *ibufend = iptr + width,
+ *sptr;
+ T *start_optr = optr;
+ int todo, cc, count;
+
+ while(iptr < ibufend)
+ {
+ sptr = iptr;
+ iptr += 2;
+ while ((iptr < ibufend) &&
+ ((iptr[-2] != iptr[-1]) || (iptr[-1] != iptr[0])))
+ iptr++;
+ iptr -= 2;
+ count = iptr-sptr;
+
+ while (count)
+ {
+ todo = (count > 126) ? 126: count;
+ count -= todo;
+ *optr++ = (T)(0x80 | todo);
+ while(todo--)
+ *optr++ = *sptr++;
+ }
+ sptr = iptr;
+ cc = *iptr++;
+
+ while((iptr < ibufend) && (*iptr == cc))
+ iptr++;
+ count = iptr-sptr;
+
+ while(count)
+ {
+ todo = (count > 126)? 126: count;
+ count -= todo;
+ *optr++ = (T)todo;
+ *optr++ = (T)cc;
+ }
+ }
+ *optr++ = 0;
+
+ return optr-start_optr;
+}
+
+static const char* iSGICompTable[2] =
+{
+ "NONE",
+ "RLE"
+};
+
+class imFileFormatSGI: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ unsigned char comp_type, /* sgi compression information */
+ bpc; /* bytes per channels */
+ unsigned int *starttab, /* compression control buffer */
+ *lengthtab; /* compression control buffer */
+
+public:
+ imFileFormatSGI(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatSGI() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatSGI: public imFormat
+{
+public:
+ imFormatSGI()
+ :imFormat("SGI",
+ "Silicon Graphics Image File Format",
+ "*.rgb;*.rgba;*.bw;*.sgi;",
+ iSGICompTable,
+ 2,
+ 0)
+ {}
+ ~imFormatSGI() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatSGI(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+void imFormatRegisterSGI(void)
+{
+ imFormatRegister(new imFormatSGI());
+}
+
+int imFileFormatSGI::Open(const char* file_name)
+{
+ unsigned short word_value;
+
+ /* opens the binary file for reading with motorola byte order */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_BIGENDIAN);
+
+ /* reads the SGI format identifier */
+ imBinFileRead(handle, &word_value, 1, 2);
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (word_value != SGI_ID)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ /* reads the compression information */
+ imBinFileRead(handle, &this->comp_type, 1, 1);
+ if (this->comp_type == SGI_RLE)
+ strcpy(this->compression, "RLE");
+ else if (this->comp_type == SGI_VERBATIM)
+ strcpy(this->compression, "NONE");
+ else
+ {
+ imBinFileClose(handle);
+ return IM_ERR_COMPRESS;
+ }
+
+ this->starttab = NULL;
+ this->lengthtab = NULL;
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatSGI::New(const char* file_name)
+{
+ /* opens the binary file for writing with motorola byte order */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_BIGENDIAN);
+
+ this->starttab = NULL;
+ this->lengthtab = NULL;
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatSGI::Close()
+{
+ if (this->starttab) free(this->starttab);
+ if (this->lengthtab) free(this->lengthtab);
+ imBinFileClose(handle);
+}
+
+void* imFileFormatSGI::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatSGI::ReadImageInfo(int index)
+{
+ (void)index;
+ unsigned short word_value, dimension, depth;
+
+ /* reads the number of bits per channel */
+ imBinFileRead(handle, &this->bpc, 1, 1);
+
+ /* reads the number of dimensions */
+ imBinFileRead(handle, &dimension, 1, 2);
+
+ /* reads the image width */
+ imBinFileRead(handle, &word_value, 1, 2);
+ this->width = word_value;
+
+ /* reads the image height */
+ imBinFileRead(handle, &word_value, 1, 2);
+ this->height = word_value;
+
+ /* reads the number of channels */
+ imBinFileRead(handle, &depth, 1, 2);
+
+ /* jump 12 bytes (min, max, dummy) */
+ imBinFileSeekOffset(handle, 12);
+
+ /* reads the image name */
+ char image_name[80];
+ imBinFileRead(handle, image_name, 80, 1);
+
+ if (image_name[0] != 0)
+ AttribTable()->Set("Description", IM_BYTE, imStrNLen(image_name, 80)+1, image_name);
+
+ /* reads the color map information */
+ unsigned int color_map_id;
+ imBinFileRead(handle, &color_map_id, 1, 4);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ this->file_data_type = IM_BYTE;
+ if (this->bpc == 2)
+ this->file_data_type = IM_USHORT;
+
+ switch (dimension)
+ {
+ case 1:
+ this->height = 1;
+ depth = 1;
+ case 2:
+ depth = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ switch (color_map_id)
+ {
+ case SGI_NORMAL:
+ switch(depth)
+ {
+ case 1:
+ this->file_color_mode = IM_GRAY;
+ break;
+ case 3:
+ this->file_color_mode = IM_RGB;
+ break;
+ case 4:
+ this->file_color_mode = IM_RGB | IM_ALPHA;
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+ break;
+ case SGI_DITHERED:
+ this->file_color_mode = IM_MAP;
+ break;
+ case SGI_COLORMAP:
+ this->file_color_mode = IM_RGB;
+ break;
+ case SGI_SCREEN:
+ this->file_color_mode = IM_GRAY;
+ break;
+ default:
+ return IM_ERR_DATA;
+ }
+
+ /* jump 404 bytes (dummy) */
+ imBinFileSeekOffset(handle, 404);
+
+ if (this->comp_type == SGI_RLE)
+ {
+ int tablen = this->height * depth;
+ this->starttab = (unsigned int *)malloc(tablen * sizeof(int));
+ this->lengthtab = (unsigned int *)malloc(tablen * sizeof(int));
+
+ /* reads the compression control information */
+ imBinFileRead(handle, this->starttab, tablen, 4);
+ imBinFileRead(handle, this->lengthtab, tablen, 4);
+
+ // allocates more than enough since compression algoritm can be ineficient
+ this->line_buffer_extra = 2*imImageLineSize(this->width, this->file_color_mode, this->file_data_type);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (color_map_id == SGI_DITHERED)
+ {
+ static int red[8] = {0, 36, 73, 109, 146, 182, 218, 255};
+ static int green[8] = {0, 36, 73, 109, 146, 182, 218, 255};
+ static int blue[4] = {0, 85, 170, 255};
+
+ int c = 0;
+ for (int b = 0; b < 4; b++)
+ {
+ for (int g = 0; g < 8; g++)
+ {
+ for (int r = 0; r < 8; r++)
+ {
+ this->palette[c] = imColorEncode((imbyte)red[r],
+ (imbyte)green[g],
+ (imbyte)blue[b]);
+ c++;
+ }
+ }
+ }
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatSGI::WriteImageInfo()
+{
+ unsigned int dword_value;
+ unsigned short word_value;
+ unsigned char dummy[404];
+ memset(dummy, 0, 404);
+
+ this->comp_type = SGI_VERBATIM;
+ if (imStrEqual(this->compression, "RLE"))
+ this->comp_type = SGI_RLE;
+
+ unsigned int color_map_id = SGI_NORMAL;
+
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+
+ int dimension = 2;
+ if (this->file_color_mode == IM_BINARY)
+ this->convert_bpp = -1; // expand 1 to 255
+ else if (this->file_color_mode == IM_RGB)
+ {
+ dimension = 3;
+ if (imColorModeHasAlpha(this->user_color_mode))
+ this->file_color_mode |= IM_ALPHA;
+ }
+
+ this->file_data_type = this->user_data_type;
+
+ this->bpc = 1;
+ int max = 255;
+ if (this->file_data_type == IM_USHORT)
+ {
+ max = 65535;
+ this->bpc = 2;
+ }
+
+ this->starttab = NULL;
+ this->lengthtab = NULL;
+
+ /* writes the SGI file header */
+ word_value = SGI_ID;
+ imBinFileWrite(handle, &word_value, 1, 2); /* identifier */
+ imBinFileWrite(handle, &this->comp_type, 1, 1); /* storage */
+ imBinFileWrite(handle, &this->bpc, 1, 1); /* bpc */
+ word_value = (imushort)dimension;
+ imBinFileWrite(handle, &word_value, 1, 2); /* dimension */
+ word_value = (unsigned short)this->width;
+ imBinFileWrite(handle, &word_value, 1, 2); /* image width */
+ word_value = (unsigned short)this->height;
+ imBinFileWrite(handle, &word_value, 1, 2); /* image height */
+ word_value = (imushort)imColorModeDepth(this->file_color_mode);
+ imBinFileWrite(handle, &word_value, 1, 2); /* depth */
+ dword_value = 0;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* min */
+ dword_value = max;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* max */
+ imBinFileWrite(handle, dummy, 4, 1); /* dummy */
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ int size;
+ char* image_name = (char*)AttribTable()->Get("Description", NULL, &size);
+ if (image_name)
+ {
+ if (size < 80)
+ {
+ imBinFileWrite(handle, image_name, size, 1);
+ imBinFileWrite(handle, dummy, 80-size, 1);
+ }
+ else
+ {
+ imBinFileWrite(handle, image_name, 79, 1);
+ imBinFileWrite(handle, (void*)"\0", 1, 1);
+ }
+ }
+ else
+ imBinFileWrite(handle, dummy, 80, 1); /* empty image name */
+
+ dword_value = color_map_id;
+ imBinFileWrite(handle, &dword_value, 1, 4); /* color_map_id */
+ imBinFileWrite(handle, dummy, 404, 1); /* dummy */
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->comp_type == SGI_RLE)
+ {
+ int tablen = this->height * imColorModeDepth(this->file_color_mode);
+ this->starttab = (unsigned int *)malloc(tablen*4);
+ this->lengthtab = (unsigned int *)malloc(tablen*4);
+
+ /* writes the empty compression control information */
+ /* we will write again at the end */
+ imBinFileWrite(handle, this->starttab, tablen*4, 1);
+ imBinFileWrite(handle, this->lengthtab, tablen*4, 1);
+
+ // allocates more than enough since compression algoritm can be ineficient
+ this->line_buffer_extra = 2*imImageLineSize(this->width, this->file_color_mode, this->file_data_type);
+ }
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatSGI::ReadImageData(void* data)
+{
+ int count = imFileLineBufferCount(this);
+
+ imCounterTotal(this->counter, count, "Reading SGI...");
+
+ imbyte* compressed_buffer = NULL;
+ if (this->comp_type == SGI_RLE) // point to the extra buffer
+ compressed_buffer = (imbyte*)this->line_buffer + this->line_buffer_size;
+
+ int row = 0, plane = 0;
+ for (int i = 0; i < count; i++)
+ {
+ if (this->comp_type == SGI_VERBATIM)
+ {
+ imBinFileRead(handle, this->line_buffer, this->line_buffer_size/this->bpc, this->bpc);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ int row_index = row + plane*this->height;
+ imBinFileSeekTo(handle, this->starttab[row_index]);
+ imBinFileRead(handle, compressed_buffer, this->lengthtab[row_index] / this->bpc, this->bpc);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->bpc == 1)
+ iSGIDecodeScanLine((imbyte*)this->line_buffer, compressed_buffer, this->width);
+ else
+ iSGIDecodeScanLine((imushort*)this->line_buffer, (imushort*)compressed_buffer, this->width);
+ }
+
+ imFileLineBufferRead(this, data, row, plane);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+
+ imFileLineBufferInc(this, &row, &plane);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatSGI::WriteImageData(void* data)
+{
+ int count = imFileLineBufferCount(this);
+
+ imCounterTotal(this->counter, count, "Writing SGI...");
+
+ imbyte* compressed_buffer = NULL;
+ if (this->comp_type == SGI_RLE) // point to the extra buffer
+ compressed_buffer = (imbyte*)this->line_buffer + this->line_buffer_size;
+
+ int row = 0, plane = 0;
+ for (int i = 0; i < count; i++)
+ {
+ imFileLineBufferWrite(this, data, row, plane);
+
+ if (this->comp_type == SGI_VERBATIM)
+ imBinFileWrite(handle, this->line_buffer, this->line_buffer_size/this->bpc, this->bpc);
+ else
+ {
+ int length;
+ if (this->bpc == 1)
+ length = iSGIEncodeScanLine(compressed_buffer, (imbyte*)this->line_buffer, this->width);
+ else
+ length = iSGIEncodeScanLine((imushort*)compressed_buffer, (imushort*)this->line_buffer, this->width);
+
+ int row_index = row + plane*this->height;
+ this->starttab[row_index] = imBinFileTell(handle);
+ this->lengthtab[row_index] = length*this->bpc;
+
+ imBinFileWrite(handle, compressed_buffer, length, this->bpc);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+
+ imFileLineBufferInc(this, &row, &plane);
+ }
+
+ if (this->comp_type == SGI_RLE)
+ {
+ imBinFileSeekTo(this->handle, 512);
+ int tablen = this->height * imColorModeDepth(this->file_color_mode);
+ imBinFileWrite(handle, this->starttab, tablen, 4);
+ imBinFileWrite(handle, this->lengthtab, tablen, 4);
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFormatSGI::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK || color_space == IM_MAP)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE && data_type != IM_USHORT)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE") && !imStrEqual(compression, "RLE"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_tga.cpp b/im/src/im_format_tga.cpp
new file mode 100755
index 0000000..86e968a
--- /dev/null
+++ b/im/src/im_format_tga.cpp
@@ -0,0 +1,1113 @@
+/** \file
+ * \brief TGA - Truevision Graphics Adapter File
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_tga.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_util.h"
+#include "im_format_all.h"
+#include "im_counter.h"
+#include "im_math.h"
+
+#include "im_binfile.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <time.h>
+#include <math.h>
+
+
+/*
+|--------|--------|------------------------------------------------------------|
+| 0 | 1 | Number of Characters in Identification Field. |
+| | | This field is a one-byte unsigned integer, specifying |
+| | | the length of the Image Identification Field. Its range |
+| | | is 0 to 255. A value of 0 means that no Image |
+| | | Identification Field is included. |
+|--------|--------|------------------------------------------------------------|
+| 1 | 1 | Color Map Type. |
+|--------|--------|------------------------------------------------------------|
+| 2 | 1 | Image Type Code. |
+|--------|--------|------------------------------------------------------------|
+| 3 | 5 | Color Map Specification. |
+| 3 | 2 | Color Map Origin. |
+| | | Integer ( lo-hi ) index of first color map entry. |
+| 5 | 2 | Color Map Length. |
+| | | Integer ( lo-hi ) count of color map entries. |
+| 7 | 1 | Color Map Entry Size. |
+| | | Number of bits in each color map entry. 16 for |
+| | | the Targa 16, 24 for the Targa 24, 32 for the Targa 32. |
+|--------|--------|------------------------------------------------------------|
+| 8 | 10 | Image Specification. |
+| 8 | 2 | X Origin of Image. |
+| | | Integer ( lo-hi ) X coordinate of the lower left corner |
+| | | of the image. |
+| 10 | 2 | Y Origin of Image. |
+| | | Integer ( lo-hi ) Y coordinate of the lower left corner |
+| | | of the image. |
+| 12 | 2 | Width of Image. |
+| | | Integer ( lo-hi ) width of the image in pixels. |
+| 14 | 2 | Height of Image. |
+| | | Integer ( lo-hi ) height of the image in pixels. |
+| 16 | 1 | Image Pixel Size. |
+| | | Number of bits in a stored pixel index. |
+| 17 | 1 | Image Descriptor Byte. |
+| | | Bits 3-0 - number of attribute bits associated with each |
+| | | pixel. |
+| | | Bit 4 - reserved. Must be set to 0. |
+| | | Bit 5 - screen origin bit. |
+| | | 0 = Origin in lower left-hand corner. |
+| | | 1 = Origin in upper left-hand corner. |
+| | | Must be 0 for Truevision images. |
+| | | Bits 7-6 - Data storage interleaving flag. |
+| | | 00 = non-interleaved. |
+| | | 01 = two-way (even/odd) interleaving. |
+| | | 10 = four way interleaving. |
+| | | 11 = reserved. |
+| | | This entire byte should be set to 0. Don't ask me. |
+|--------|--------|------------------------------------------------------------|
+| 18 | varies | Image Identification Field. |
+| | | Contains a free-form identification field of the length |
+| | | specified in byte 1 of the image record. It's usually |
+| | | omitted ( length in byte 1 = 0 ), but can be up to 255 |
+| | | characters. If more identification information is |
+| | | required, it can be stored after the image data. |
+|--------|--------|------------------------------------------------------------|
+
+Extension Area:
+
+* The inclusion of a scaled-down “postage stamp” copy of the image
+* Date and Time of image file creation
+* Author Name
+* Author Comments
+* Job Name
+* Job Accumulated Time
+* Gamma Value
+* Correct Color LUT
+* Pixel Aspect Ratio
+* Scan Line Offset Table
+* Key Color
+* Software Package Name and Version Number
+* Developer Definable Areas
+* Attribute (Alpha) channel Type
+* The ability for simple expansion
+*/
+
+static int iTGADecodeScanLine(imBinFile* handle, imbyte *DecodedBuffer, int width, int pixel_size)
+{
+ int i=0;
+ unsigned char runcount; /* repetition count field */
+ imbyte pixel_buffer[4];
+
+ while (i < width)
+ {
+ imBinFileRead(handle, &runcount, 1, 1);
+
+ if (runcount & 0x80)
+ {
+ imBinFileRead(handle, pixel_buffer, pixel_size, 1);
+ runcount &= 0x7F;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ runcount++;
+ while (runcount-- && i < width)
+ {
+ memcpy(DecodedBuffer, pixel_buffer, pixel_size);
+ i++;
+ DecodedBuffer += pixel_size;
+ }
+ }
+ else
+ {
+ runcount++;
+ while (runcount-- && i < width)
+ {
+ imBinFileRead(handle, pixel_buffer, pixel_size, 1);
+ memcpy(DecodedBuffer, pixel_buffer, pixel_size);
+ i++;
+ DecodedBuffer += pixel_size;
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+ }
+
+ return IM_ERR_NONE;
+}
+
+static inline int iTGAEqualPixel(const imbyte* Buffer1, const imbyte* Buffer2, int pixel_size)
+{
+ while(pixel_size--)
+ {
+ if (*Buffer1++ != *Buffer2++)
+ return 0;
+ }
+ return 1;
+}
+
+static int iTGAEncodeScanLine(imbyte* EncodedBuffer, const imbyte* DecodedBuffer, int width, int pixel_size)
+{
+ imbyte pixel_buffer[4];
+ unsigned char runcount; /* Length of encoded pixel run */
+ int x = 0; /* Index into uncompressed data buffer */
+ imbyte* StartBuffer = EncodedBuffer;
+
+ while (x < width)
+ {
+ runcount = 1;
+ memcpy(pixel_buffer, &DecodedBuffer[x*pixel_size], pixel_size);
+
+ // count equal pixels
+ while (x+runcount < width && runcount < 128 &&
+ iTGAEqualPixel(pixel_buffer, &DecodedBuffer[(x+runcount)*pixel_size], pixel_size))
+ runcount++;
+
+ if (runcount == 1)
+ {
+ // count different pixels
+ while (x+runcount+1 < width && runcount < 128)
+ {
+ memcpy(pixel_buffer, &DecodedBuffer[(x+runcount)*pixel_size], pixel_size);
+
+ if (!iTGAEqualPixel(pixel_buffer, &DecodedBuffer[(x+runcount+1)*pixel_size], pixel_size))
+ runcount++;
+ else
+ break;
+ }
+
+ *EncodedBuffer++ = (imbyte)(runcount-1);
+
+ memcpy(EncodedBuffer, &DecodedBuffer[x*pixel_size], runcount*pixel_size);
+ EncodedBuffer += runcount*pixel_size;
+ }
+ else
+ {
+ *EncodedBuffer++ = (imbyte)(0x80 | (runcount-1));
+
+ memcpy(EncodedBuffer, pixel_buffer, pixel_size);
+ EncodedBuffer += pixel_size;
+ }
+
+ x += runcount;
+ }
+
+ return EncodedBuffer-StartBuffer; /* Return the number of unsigned chars written to buffer */
+}
+
+static const char* iTGACompTable[2] =
+{
+ "NONE",
+ "RLE"
+};
+
+class imFileFormatTGA: public imFileFormatBase
+{
+ imBinFile* handle; /* the binary file handle */
+ unsigned char id_lenght;
+ unsigned char map_type, image_type, map_bpp, bpp;
+
+ int ReadPalette();
+ int WritePalette();
+ void FixRGB();
+ int LoadExtensionArea();
+ int SaveExtensionArea();
+
+public:
+ imFileFormatTGA(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatTGA() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatTGA: public imFormat
+{
+public:
+ imFormatTGA()
+ :imFormat("TGA",
+ "Truevision Graphics Adapter File",
+ "*.tga;*.icb;*.vst;*.tpic;",
+ iTGACompTable,
+ 2,
+ 0)
+ {}
+ ~imFormatTGA() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatTGA(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+void imFormatRegisterTGA(void)
+{
+ imFormatRegister(new imFormatTGA());
+}
+
+int imFileFormatTGA::Open(const char* file_name)
+{
+ /* opens the binary file for reading with intel byte order */
+ handle = imBinFileOpen(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ imBinFileRead(handle, &this->id_lenght, 1, 1);
+ imBinFileRead(handle, &this->map_type, 1, 1);
+ imBinFileRead(handle, &this->image_type, 1, 1);
+
+ if (imBinFileError(handle))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_ACCESS;
+ }
+
+ if (this->image_type != 1 && this->image_type != 2 && this->image_type != 3 &&
+ this->image_type != 9 && this->image_type != 10 && this->image_type != 11)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ if (this->map_type != 0 && this->map_type != 1)
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ if (this->map_type == 0 && (this->image_type == 1 || this->image_type == 9))
+ {
+ imBinFileClose(handle);
+ return IM_ERR_FORMAT;
+ }
+
+ if (this->image_type == 9 || this->image_type == 10 || this->image_type == 11)
+ strcpy(this->compression, "RLE");
+ else
+ strcpy(this->compression, "NONE");
+
+ this->image_count = 1;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatTGA::New(const char* file_name)
+{
+ /* opens the binary file for writing with intel byte order */
+ handle = imBinFileNew(file_name);
+ if (!handle)
+ return IM_ERR_OPEN;
+
+ imBinFileByteOrder(handle, IM_LITTLEENDIAN);
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatTGA::Close()
+{
+ imBinFileClose(handle);
+}
+
+void* imFileFormatTGA::Handle(int index)
+{
+ if (index == 0)
+ return (void*)this->handle;
+ else
+ return NULL;
+}
+
+int imFileFormatTGA::ReadImageInfo(int index)
+{
+ (void)index;
+ unsigned char byte_value;
+ unsigned short word_value;
+
+ this->file_data_type = IM_BYTE;
+
+ if (this->image_type == 1 || this->image_type == 9)
+ this->file_color_mode = IM_MAP;
+ else if (this->image_type == 2 || this->image_type == 10)
+ {
+ this->file_color_mode = IM_RGB;
+ this->file_color_mode |= IM_PACKED;
+ }
+ else if (this->image_type == 3 || this->image_type == 11)
+ this->file_color_mode = IM_GRAY;
+ else
+ return IM_ERR_DATA;
+
+ if (this->map_type == 0)
+ imBinFileSeekOffset(handle, 5); // jump color map information
+ else
+ {
+ /* jump 2 bytes (first entry index) */
+ imBinFileSeekOffset(handle, 2);
+
+ imBinFileRead(handle, &word_value, 1, 2);
+ this->palette_count = word_value;
+
+ imBinFileRead(handle, &this->map_bpp, 1, 1);
+
+ if (this->map_bpp == 15) this->map_bpp = 16;
+
+ if (this->map_bpp != 16 && this->map_bpp != 24 && this->map_bpp != 32)
+ return IM_ERR_DATA;
+ }
+
+ /* jump 4 bytes (X-Origin, Y-Origin) */
+ unsigned short xmin, ymin;
+ imBinFileRead(handle, &xmin, 1, 2);
+ imBinFileRead(handle, &ymin, 1, 2);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ if (xmin && ymin)
+ {
+ attrib_table->Set("XScreen", IM_USHORT, 1, &xmin);
+ attrib_table->Set("YScreen", IM_USHORT, 1, &ymin);
+ }
+
+ /* reads the image width */
+ imBinFileRead(handle, &word_value, 1, 2);
+ this->width = word_value;
+
+ /* reads the image height */
+ imBinFileRead(handle, &word_value, 1, 2);
+ this->height = word_value;
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ imBinFileRead(handle, &this->bpp, 1, 1);
+
+ if (this->bpp > 8 && imColorModeSpace(this->file_color_mode) != IM_RGB)
+ return IM_ERR_DATA;
+
+ if (this->bpp == 15) this->bpp = 16;
+
+ if (this->bpp != 8 && this->bpp != 16 &&
+ this->bpp != 24 && this->bpp != 32)
+ return IM_ERR_DATA;
+
+ if (this->bpp == 32)
+ this->file_color_mode |= IM_ALPHA;
+
+ // image descriptor
+ imBinFileRead(handle, &byte_value, 1, 1);
+
+ if (byte_value & 0x20)
+ this->file_color_mode |= IM_TOPDOWN;
+
+ // image ID
+ if (this->id_lenght)
+ {
+ char desc[256];
+ imBinFileRead(handle, desc, this->id_lenght, 1);
+ desc[this->id_lenght] = 0;
+ attrib_table->Set("Title", IM_BYTE, this->id_lenght+1, desc);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->map_type)
+ {
+ if (!ReadPalette())
+ return IM_ERR_ACCESS;
+ }
+
+ long cur_offset = imBinFileTell(handle);
+ imBinFileSeekFrom(handle, -18);
+ char ext_sig[18];
+ imBinFileRead(handle, ext_sig, 18, 1);
+ if (ext_sig[17] == 0 && imStrEqual(ext_sig, "TRUEVISION-XFILE."))
+ {
+ if (!LoadExtensionArea())
+ return IM_ERR_ACCESS;
+ }
+ imBinFileSeekTo(handle, cur_offset);
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatTGA::WriteImageInfo()
+{
+ unsigned char byte_value;
+ unsigned short word_value;
+
+ this->map_bpp = 0;
+ this->map_type = 0;
+
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+ switch (this->file_color_mode)
+ {
+ case IM_BINARY:
+ this->convert_bpp = -1; // expand 1 to 255
+ case IM_GRAY:
+ this->bpp = 8;
+ if (imStrEqual(this->compression, "RLE"))
+ this->image_type = 11;
+ else
+ this->image_type = 3;
+ break;
+ case IM_MAP:
+ this->bpp = 8;
+ this->map_bpp = 24;
+ this->map_type = 1;
+ if (imStrEqual(this->compression, "RLE"))
+ this->image_type = 9;
+ else
+ this->image_type = 1;
+ break;
+ case IM_RGB:
+ this->bpp = 24;
+ this->file_color_mode |= IM_PACKED;
+ if (imStrEqual(this->compression, "RLE"))
+ this->image_type = 10;
+ else
+ this->image_type = 2;
+ break;
+ }
+
+ if (this->image_type > 3)
+ {
+ // allocates more than enough since compression algoritm can be ineficient
+ this->line_buffer_extra += 2*this->width*imColorModeDepth(this->file_color_mode);
+ }
+
+ imAttribTable* attrib_table = AttribTable();
+
+ /* writes the TGA file header */
+
+ int length = 0;
+ const char* desc_attrib = (const char*)attrib_table->Get("Title", NULL, &length);
+ if (desc_attrib)
+ {
+ if (length > 255)
+ this->id_lenght = 255;
+ else
+ this->id_lenght = (imbyte)length;
+ }
+ else
+ this->id_lenght = 0;
+
+ /* IDLength */
+ imBinFileWrite(handle, &this->id_lenght, 1, 1);
+
+ /* Color Map Type */
+ imBinFileWrite(handle, &this->map_type, 1, 1);
+
+ /* Image Type */
+ imBinFileWrite(handle, &this->image_type, 1, 1);
+
+ /* Color Map Specification - 1st entry index */
+ word_value = 0;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ /* Color map length */
+ word_value = (unsigned short) this->palette_count;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ /* Color Map Entry size */
+ byte_value = this->map_type? this->map_bpp: (imbyte)0;
+ imBinFileWrite(handle, &byte_value, 1, 1);
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ unsigned short xmin = 0, ymin = 0;
+ const void* attrib_data = attrib_table->Get("XScreen");
+ if (attrib_data) xmin = *(unsigned short*)attrib_data;
+ attrib_data = attrib_table->Get("YScreen");
+ if (attrib_data) ymin = *(unsigned short*)attrib_data;
+
+ /* X-orign of image */
+ word_value = xmin;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ /* Y-orign of image */
+ word_value = ymin;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ /* Image Width */
+ word_value = (imushort)this->width;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ /* Image Height */
+ word_value = (imushort)this->height;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ /* Pixel Depth */
+ imBinFileWrite(handle, &this->bpp, 1, 1);
+
+ /* Image Descriptor */
+ byte_value = 0x00;
+ imBinFileWrite(handle, &byte_value, 1, 1);
+
+ /* image ID */
+ if (this->id_lenght)
+ {
+ if (length > 255)
+ {
+ imBinFileWrite(handle, (void*)desc_attrib, 254, 1);
+ byte_value = 0x00;
+ imBinFileWrite(handle, &byte_value, 1, 1);
+ }
+ else
+ imBinFileWrite(handle, (void*)desc_attrib, this->id_lenght, 1);
+ }
+
+ /* tests if everything was ok */
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (this->map_type)
+ {
+ if (!WritePalette())
+ return IM_ERR_ACCESS;
+ }
+
+ return IM_ERR_NONE;
+}
+
+static long iTGARGB2Color(int c, unsigned char *colors, int map_bpp)
+{
+ unsigned char r,g,b;
+
+ if (map_bpp == 16)
+ {
+ unsigned short word_value = ((unsigned short*)colors)[c];
+
+ r = (imbyte)(((word_value & 0x7C00) >> 10)*8);
+ g = (imbyte)(((word_value & 0x03E0) >> 5)*8);
+ b = (imbyte)( (word_value & 0x001F) *8);
+ }
+ else // 24 or 32
+ {
+ int i = c * (map_bpp / 8);
+
+ r = colors[i+2];
+ g = colors[i+1];
+ b = colors[i];
+ }
+
+ return imColorEncode(r, g, b);
+}
+
+int imFileFormatTGA::ReadPalette()
+{
+ int map_size = imFileLineSizeAligned(this->palette_count, this->map_bpp, 1);
+ unsigned char* tga_colors = (unsigned char*) malloc(map_size);
+
+ /* reads the color palette */
+ imBinFileRead(handle, tga_colors, map_size, 1);
+ if (imBinFileError(handle))
+ return 0;
+
+ if (imBinCPUByteOrder() == IM_BIGENDIAN && this->map_bpp == 16)
+ imBinSwapBytes2(tga_colors, map_size/2);
+
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ this->palette[c] = iTGARGB2Color(c, tga_colors, this->map_bpp);
+
+ free(tga_colors);
+
+ return 1;
+}
+
+int imFileFormatTGA::WritePalette()
+{
+ unsigned char tga_color[256*3];
+
+ /* convert the color map from the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = 3*c;
+ imColorDecode(&tga_color[i+2], &tga_color[i+1], &tga_color[i], this->palette[c]);
+ }
+
+ /* writes the color palette */
+ imBinFileWrite(handle, tga_color, this->palette_count * 3, 1);
+
+ if (imBinFileError(handle))
+ return 0;
+
+ return 1;
+}
+
+int imFileFormatTGA::LoadExtensionArea()
+{
+ unsigned int dword_value;
+ imBinFileSeekFrom(handle, -26);
+
+ // extension offset
+ imBinFileRead(handle, &dword_value, 1, 4);
+ if (imBinFileError(handle))
+ return 0;
+
+ imBinFileSeekTo(handle, dword_value);
+ if (imBinFileError(handle))
+ return 0;
+
+ unsigned short word_value;
+ imbyte buffer[512];
+ imAttribTable* attrib_table = AttribTable();
+
+ // extension size
+ imBinFileSeekOffset(handle, 2);
+
+ // author name
+ imBinFileRead(handle, buffer, 41, 1);
+ if (buffer[0] != 0)
+ attrib_table->Set("Author", IM_BYTE, imStrNLen((char*)buffer, 41)+1, buffer);
+
+ // author comments
+ imBinFileRead(handle, buffer, 324, 1);
+ if (buffer[0] != 0)
+ {
+ int size1 = imStrNLen((char*)buffer, 81);
+ for (int i = 1; i < 4; i++)
+ {
+ int sizei = imStrNLen((char*)buffer + i*81, 81);
+ if (sizei)
+ {
+ memcpy(buffer + size1, buffer + i*81, sizei);
+ size1 += sizei;
+ }
+ }
+ buffer[size1] = 0;
+
+ attrib_table->Set("Description", IM_BYTE, size1+1, buffer);
+ }
+
+ if (imBinFileError(handle))
+ return 0;
+
+ {
+ tm ttm;
+ ttm.tm_wday = 0;
+ ttm.tm_yday = 0;
+ ttm.tm_isdst = -1;
+
+ int valid = 0;
+ imBinFileRead(handle, &word_value, 1, 2); // moth
+ ttm.tm_mon = word_value-1;
+ if (word_value) valid = 1;
+ imBinFileRead(handle, &word_value, 1, 2); // day
+ ttm.tm_mday = word_value;
+ if (word_value) valid = 1;
+ imBinFileRead(handle, &word_value, 1, 2); // year
+ ttm.tm_year = word_value-1900;
+ if (word_value) valid = 1;
+ imBinFileRead(handle, &word_value, 1, 2); // hour
+ ttm.tm_hour = word_value;
+ imBinFileRead(handle, &word_value, 1, 2); // minute
+ ttm.tm_min = word_value;
+ imBinFileRead(handle, &word_value, 1, 2); // seconds
+ ttm.tm_sec = word_value;
+
+ if (imBinFileError(handle))
+ return 0;
+
+ if (valid)
+ {
+ time_t tt = mktime(&ttm);
+ char* str = ctime(&tt);
+ if (str)
+ {
+ int size = strlen(str);
+ str[size-1] = 0; // remove "\n"
+ attrib_table->Set("DateTimeModified", IM_BYTE, size, str);
+ }
+ }
+ }
+
+ // job name
+ imBinFileRead(handle, buffer, 41, 1);
+ if (buffer[0] != 0)
+ attrib_table->Set("JobName", IM_BYTE, imStrNLen((char*)buffer, 41)+1, buffer);
+
+ // job time
+ imBinFileSeekOffset(handle, 6);
+
+ // Software
+ imBinFileRead(handle, buffer, 41, 1);
+ if (buffer[0] != 0)
+ attrib_table->Set("Software", IM_BYTE, imStrNLen((char*)buffer, 41)+1, buffer);
+
+ if (imBinFileError(handle))
+ return 0;
+
+ // Software Version
+ imBinFileRead(handle, &word_value, 1, 2);
+ if (word_value)
+ {
+ int size = sprintf((char*)buffer, "%f", (double)word_value / 100.0);
+ imBinFileRead(handle, &buffer[size], 1, 1);
+ buffer[size+1] = 0;
+ attrib_table->Set("SoftwareVersion", IM_BYTE, size+1, buffer);
+ }
+
+ // key color, aspect ratio
+ imBinFileSeekOffset(handle, 8);
+
+ // gamma
+ imBinFileRead(handle, &word_value, 1, 2); // num
+ if (word_value)
+ {
+ float gamma = (float)word_value;
+ imBinFileRead(handle, &word_value, 1, 2); // den
+ if (word_value)
+ {
+ gamma /= (float)word_value;
+ attrib_table->Set("Gamma", IM_FLOAT, 1, &gamma);
+ }
+ }
+
+ if (imBinFileError(handle))
+ return 0;
+
+ return 1;
+}
+
+static void iGetRational(float fvalue, int *num, int *den)
+{
+ if (floorf(fvalue) == fvalue)
+ {
+ *num = (int)floorf(fvalue);
+ *den = 1;
+ return;
+ }
+
+ float ivalue = 1.0f/fvalue;
+ if (floorf(ivalue) == ivalue)
+ {
+ *den = (int)floorf(ivalue);
+ *num = 1;
+ return;
+ }
+
+ *den = 1;
+ if (fvalue > 0)
+ {
+ while (fvalue < 1L<<(31-3) && *den < 1L<<(31-3))
+ {
+ fvalue *= 1<<3;
+ *den *= 1<<3;
+ }
+ }
+
+ *num = imRound(fvalue);
+}
+
+int imFileFormatTGA::SaveExtensionArea()
+{
+ unsigned int dword_value;
+ unsigned short word_value;
+
+ // get offset before write
+ long ext_offset = imBinFileTell(handle);
+
+ imbyte buffer[512];
+ memset(buffer, 0, 512);
+
+ imAttribTable* attrib_table = AttribTable();
+
+ // extension size
+ word_value = 495;
+ imBinFileWrite(handle, &word_value, 1, 2);
+
+ // author name
+ int attrib_size;
+ const void* attrib_data = attrib_table->Get("Author", NULL, &attrib_size);
+ if (attrib_data)
+ {
+ int size = attrib_size > 41? 40: attrib_size;
+ imBinFileWrite(handle, (void*)attrib_data, size, 1);
+ if (size < 41)
+ imBinFileWrite(handle, buffer, 41-size, 1);
+ }
+ else
+ imBinFileWrite(handle, buffer, 41, 1);
+
+ // author comments
+ attrib_data = attrib_table->Get("Description", NULL, &attrib_size);
+ if (attrib_data)
+ {
+ int size = 0, size2 = 0, i = 0;
+ while(attrib_size && i < 4)
+ {
+ int line_size;
+ if (attrib_size > 81)
+ line_size = 80;
+ else
+ line_size = attrib_size;
+
+ memcpy(buffer + size, (imbyte*)attrib_data + size2, line_size);
+
+ attrib_size -= line_size;
+ size2 += line_size;
+ size += line_size;
+ i++;
+
+ int remain = 81-line_size;
+ if (remain)
+ {
+ memset(buffer + size, 0, remain);
+ size += remain;
+ }
+ }
+
+ imBinFileWrite(handle, buffer, 324, 1);
+ memset(buffer, 0, 512);
+ }
+ else
+ imBinFileWrite(handle, buffer, 324, 1);
+
+ if (imBinFileError(handle))
+ return 0;
+
+ attrib_data = attrib_table->Get("DateTimeModified");
+ if (attrib_data)
+ {
+ time_t cur_time;
+ time(&cur_time);
+ tm* ttm = localtime(&cur_time);
+
+ word_value = (imushort)ttm->tm_mon+1;
+ imBinFileWrite(handle, &word_value, 1, 2); // moth
+ word_value = (imushort)ttm->tm_mday;
+ imBinFileWrite(handle, &word_value, 1, 2); // day
+ word_value = (imushort)ttm->tm_year+1900;
+ imBinFileWrite(handle, &word_value, 1, 2); // year
+ word_value = (imushort)ttm->tm_hour;
+ imBinFileWrite(handle, &word_value, 1, 2); // hour
+ word_value = (imushort)ttm->tm_min;
+ imBinFileWrite(handle, &word_value, 1, 2); // minute
+ word_value = (imushort)ttm->tm_sec;
+ imBinFileWrite(handle, &word_value, 1, 2); // seconds
+
+ if (imBinFileError(handle))
+ return 0;
+ }
+ else
+ imBinFileWrite(handle, buffer, 12, 1);
+
+ // job name
+ attrib_data = attrib_table->Get("JobName", NULL, &attrib_size);
+ if (attrib_data)
+ {
+ int size = attrib_size > 41? 40: attrib_size;
+ imBinFileWrite(handle, (void*)attrib_data, size, 1);
+ if (size < 41)
+ imBinFileWrite(handle, buffer, 41-size, 1);
+ }
+ else
+ imBinFileWrite(handle, buffer, 41, 1);
+
+ // job time
+ imBinFileWrite(handle, buffer, 6, 1);
+
+ // Software
+ attrib_data = attrib_table->Get("Software", NULL, &attrib_size);
+ if (attrib_data)
+ {
+ int size = attrib_size > 41? 40: attrib_size;
+ imBinFileWrite(handle, (void*)attrib_data, size, 1);
+ if (size < 41)
+ imBinFileWrite(handle, buffer, 41-size, 1);
+ }
+ else
+ imBinFileWrite(handle, buffer, 41, 1);
+
+ if (imBinFileError(handle))
+ return 0;
+
+ // Software Version, key color, aspect ratio
+ imBinFileWrite(handle, buffer, 11, 1);
+
+ // gamma
+ attrib_data = attrib_table->Get("Gamma");
+ if (attrib_data)
+ {
+ float gamma = *(float*)attrib_data;
+
+ int num, den;
+ iGetRational(gamma, &num, &den);
+
+ word_value = (imushort)num;
+ imBinFileWrite(handle, &word_value, 1, 2); // num
+ word_value = (imushort)den;
+ imBinFileWrite(handle, &word_value, 1, 2); // den
+ }
+ else
+ imBinFileWrite(handle, buffer, 4, 1);
+
+ // Color Correction, Postage Stamp, Scanline Offset, Attributes Type
+ imBinFileWrite(handle, buffer, 13, 1);
+
+ // FOOTER
+
+ // extension offset
+ dword_value = ext_offset;
+ imBinFileWrite(handle, &dword_value, 1, 4);
+
+ // Developer Directory Offset
+ imBinFileWrite(handle, buffer, 4, 1);
+
+ // signature, reserved, zero string terminator
+ imBinFileWrite(handle, (void*)"TRUEVISION-XFILE.\0", 18, 1);
+
+ if (imBinFileError(handle))
+ return 0;
+
+ return 1;
+}
+
+void imFileFormatTGA::FixRGB()
+{
+ int x;
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+
+ if (this->bpp == 16)
+ {
+ /* inverts the WORD values if not intel */
+ if (imBinCPUByteOrder() == IM_BIGENDIAN)
+ imBinSwapBytes2(this->line_buffer, this->width);
+
+ imushort* word_data = (imushort*)this->line_buffer;
+
+ // from end to start
+ for (x = this->width-1; x >= 0; x--)
+ {
+ imushort word_value = word_data[x];
+ int c = x*3;
+ byte_data[c] = (imbyte)(((word_value & 0x7C00) >> 10)*8);
+ byte_data[c+1] = (imbyte)(((word_value & 0x03E0) >> 5)*8);
+ byte_data[c+2] = (imbyte)( (word_value & 0x001F) *8);
+ }
+ }
+ else // 24 and 32
+ {
+ // convert BGR <-> RGB
+ // convert BGRA <-> RGBA
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+ int planes = this->bpp/8;
+ for (x = 0; x < this->width; x++)
+ {
+ int c = x*planes;
+ imbyte temp = byte_data[c]; // swap R and B
+ byte_data[c] = byte_data[c+2];
+ byte_data[c+2] = temp;
+ }
+ }
+}
+
+int imFileFormatTGA::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading TGA...");
+
+ int line_size = this->line_buffer_size;
+ if (this->bpp == 16)
+ line_size = this->width*2;
+
+ for (int row = 0; row < this->height; row++)
+ {
+ if (this->image_type > 3)
+ {
+ if (iTGADecodeScanLine(handle, (imbyte*)this->line_buffer, this->width, this->bpp/8) == IM_ERR_ACCESS)
+ return IM_ERR_ACCESS;
+ }
+ else
+ {
+ imBinFileRead(handle, this->line_buffer, line_size, 1);
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+ }
+
+ if (this->bpp > 8)
+ FixRGB();
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatTGA::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing TGA...");
+
+ imbyte* compressed_buffer = NULL;
+ if (this->image_type > 3) // point to the extra buffer
+ compressed_buffer = (imbyte*)this->line_buffer + this->line_buffer_size;
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ if (this->bpp > 8)
+ FixRGB();
+
+ if (this->image_type > 3)
+ {
+ int compressed_size = iTGAEncodeScanLine(compressed_buffer, (imbyte*)this->line_buffer, this->width, this->bpp/8);
+ imBinFileWrite(handle, compressed_buffer, compressed_size, 1);
+ }
+ else
+ {
+ imBinFileWrite(handle, this->line_buffer, this->line_buffer_size, 1);
+ }
+
+ if (imBinFileError(handle))
+ return IM_ERR_ACCESS;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ if (!SaveExtensionArea())
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+int imFormatTGA::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ if (!compression || compression[0] == 0)
+ return IM_ERR_NONE;
+
+ if (!imStrEqual(compression, "NONE") && !imStrEqual(compression, "RLE"))
+ return IM_ERR_COMPRESS;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_format_wmv.cpp b/im/src/im_format_wmv.cpp
new file mode 100755
index 0000000..4f3b31b
--- /dev/null
+++ b/im/src/im_format_wmv.cpp
@@ -0,0 +1,1633 @@
+/** \file
+ * \brief WMV - Windows Media Video Format
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_format_wmv.cpp,v 1.3 2009/08/23 23:57:52 scuri Exp $
+ */
+
+#include "im_format.h"
+#include "im_util.h"
+#include "im_format_wmv.h"
+#include "im_counter.h"
+
+#include <wmsdk.h>
+
+//#include <Dvdmedia.h>
+#define AMINTERLACE_1FieldPerSample 0x00000002
+#define AMINTERLACE_Field1First 0x00000004
+
+#include "im_dib.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+
+#define SAFE_RELEASE( x ) \
+ if ( x ) \
+ { \
+ x->Release(); \
+ x = NULL; \
+ }
+
+#define SAFE_ARRAYDELETE( x ) \
+ if ( x ) \
+ { \
+ delete[] x; \
+ x = NULL; \
+ }
+
+static HRESULT iConfigCompressedStream( IWMStreamConfig * pStreamConfig,
+ IWMProfile * pIWMProfile,
+ BOOL fIsVBR, DWORD dwBitrate, DWORD dwQuality, DWORD dwSecPerKey,
+ WM_MEDIA_TYPE * pmt )
+{
+ WORD wFALSE = 0;
+ HRESULT hr = S_OK;
+
+ do
+ {
+ // This is used just to get the stream number, it will be released and
+ // NOT added to the profile
+ IWMStreamConfig * pStreamConfig2 = NULL;
+ hr = pIWMProfile->CreateNewStream( WMMEDIATYPE_Video, &pStreamConfig2 );
+ if (FAILED(hr))
+ break;
+
+ WORD wStreamNum = 0;
+ hr = pStreamConfig2->GetStreamNumber( &wStreamNum );
+
+ SAFE_RELEASE( pStreamConfig2 );
+
+ if (FAILED(hr))
+ break;
+
+ // Configure the stream
+
+ hr = pStreamConfig->SetStreamNumber( wStreamNum );
+ if (FAILED(hr))
+ break;
+
+ hr = pStreamConfig->SetStreamName( L"Video Stream" );
+ if (FAILED(hr))
+ break;
+
+ // Each stream in the profile has to have a unique connection name.
+ // Let's use the stream number to create it.
+
+ WCHAR pwszConnectionName[10];
+ swprintf( pwszConnectionName, L"Video%d", (DWORD)wStreamNum );
+
+ hr = pStreamConfig->SetConnectionName( pwszConnectionName );
+ if (FAILED(hr))
+ break;
+
+ hr = pStreamConfig->SetBitrate( dwBitrate );
+ if (FAILED(hr))
+ break;
+
+ hr = pStreamConfig->SetBufferWindow( (DWORD)-1 );
+ if (FAILED(hr))
+ break;
+
+ IWMVideoMediaProps * pIWMMediaProps = NULL;
+ hr = pStreamConfig->QueryInterface( IID_IWMVideoMediaProps, (void **) &pIWMMediaProps );
+ if (FAILED(hr))
+ break;
+
+ hr = pIWMMediaProps->SetQuality( dwQuality );
+ hr = pIWMMediaProps->SetMaxKeyFrameSpacing( 10000 * (QWORD)dwSecPerKey );
+
+ hr = pIWMMediaProps->SetMediaType( pmt );
+
+ SAFE_RELEASE( pIWMMediaProps );
+
+ if (FAILED(hr))
+ break;
+
+ IWMPropertyVault* pPropertyVault = NULL;
+ hr = pStreamConfig->QueryInterface( IID_IWMPropertyVault, (void**)&pPropertyVault );
+ if (FAILED(hr))
+ break;
+
+ hr = pPropertyVault->SetProperty( g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE*)&fIsVBR, sizeof( BOOL ) );
+ if ( SUCCEEDED( hr ) && fIsVBR)
+ pPropertyVault->SetProperty( g_wszVBRQuality, WMT_TYPE_DWORD, (BYTE*)&dwQuality, sizeof( DWORD ) );
+
+ SAFE_RELEASE( pPropertyVault );
+
+ hr = S_OK;
+
+ } while( wFALSE );
+
+ return( hr );
+}
+
+static HRESULT iCreateCompressedStream(IWMProfileManager * pManager,
+ IWMStreamConfig* *pNewStreamConfig,
+ WM_MEDIA_TYPE* *pNewMediaType,
+ WORD biBitCount, GUID subtype)
+{
+ IWMCodecInfo * pCodecInfo = NULL;
+ IWMMediaProps * pMediaProps = NULL;
+
+ IWMStreamConfig* pStreamConfig = NULL;
+ WM_MEDIA_TYPE* pMediaType = NULL;
+
+ HRESULT hr = S_OK;
+ WORD wFALSE = 0;
+
+ do
+ {
+ hr = pManager->QueryInterface(IID_IWMCodecInfo, (void **) &pCodecInfo);
+ if (FAILED(hr))
+ break;
+
+ DWORD cCodecs;
+ hr = pCodecInfo->GetCodecInfoCount( WMMEDIATYPE_Video, &cCodecs );
+ if (FAILED(hr))
+ break;
+
+ for( int i = cCodecs-1; i >= 0; i-- )
+ {
+ DWORD cFormats;
+ hr = pCodecInfo->GetCodecFormatCount( WMMEDIATYPE_Video, i, &cFormats );
+ if (FAILED(hr))
+ break;
+
+ for(DWORD j = 0; j < cFormats; j++ )
+ {
+ SAFE_RELEASE( pStreamConfig );
+
+ hr = pCodecInfo->GetCodecFormat( WMMEDIATYPE_Video, i, j, &pStreamConfig );
+ if (FAILED(hr))
+ break;
+
+ SAFE_RELEASE( pMediaProps );
+
+ hr = pStreamConfig->QueryInterface( IID_IWMMediaProps, (void **) &pMediaProps );
+ if (FAILED(hr))
+ break;
+
+ DWORD cbMT;
+ hr = pMediaProps->GetMediaType( NULL, &cbMT );
+ if (FAILED(hr))
+ break;
+
+ SAFE_ARRAYDELETE( pMediaType );
+
+ pMediaType = (WM_MEDIA_TYPE *) new BYTE[ cbMT ];
+ if( !pMediaType )
+ {
+ hr = E_OUTOFMEMORY;
+ break;
+ }
+
+ hr = pMediaProps->GetMediaType( pMediaType, &cbMT );
+ if (FAILED(hr))
+ break;
+
+ if( pMediaType->formattype != WMFORMAT_VideoInfo ||
+ pMediaType->subtype != subtype) // This is our main target
+ {
+ SAFE_RELEASE( pStreamConfig );
+ continue;
+ }
+
+ WMVIDEOINFOHEADER* pVIH = (WMVIDEOINFOHEADER*) pMediaType->pbFormat;
+
+ if( pVIH->bmiHeader.biBitCount >= biBitCount )
+ break; // SUCCESS !!!!!
+
+ SAFE_RELEASE( pStreamConfig );
+ }
+
+ if( FAILED( hr ) || NULL != pStreamConfig )
+ break;
+ }
+
+ if (FAILED(hr))
+ break;
+
+ if( NULL == pStreamConfig )
+ {
+ hr = NS_E_VIDEO_CODEC_NOT_INSTALLED;
+ break;
+ }
+
+ } while( wFALSE );
+
+ SAFE_RELEASE( pCodecInfo );
+ SAFE_RELEASE( pMediaProps );
+
+ *pNewStreamConfig = pStreamConfig;
+ *pNewMediaType = pMediaType;
+
+ return( hr );
+}
+
+static HRESULT iAddCompressedVideoStream( IWMProfileManager * pManager, IWMProfile * pIWMProfile,
+ GUID subtype, BITMAPINFOHEADER * bmiHeader, float fps,
+ BOOL fIsVBR, DWORD dwBitRate, DWORD dwQuality, DWORD dwSecPerKey)
+{
+ HRESULT hr = S_OK;
+ WORD wFALSE = 0;
+
+ IWMStreamConfig* pStreamConfig = NULL;
+ WM_MEDIA_TYPE* pMediaType = NULL;
+
+ do
+ {
+ hr = iCreateCompressedStream(pManager, &pStreamConfig, &pMediaType,
+ bmiHeader->biBitCount, subtype);
+ if (FAILED(hr))
+ break;
+
+ WMVIDEOINFOHEADER * pVIH = (WMVIDEOINFOHEADER *) pMediaType->pbFormat;
+
+ pVIH->dwBitRate = dwBitRate;
+
+ // Video content does not play correctly unless it is encoded
+ // to a size that is a multiple of four for both width and height.
+ pVIH->bmiHeader.biWidth = ((bmiHeader->biWidth + 3) / 4) * 4;
+ pVIH->bmiHeader.biHeight = ((bmiHeader->biHeight + 3) / 4) * 4;
+
+ pVIH->rcSource.left = 0;
+ pVIH->rcSource.top = 0;
+ pVIH->rcSource.bottom = pVIH->bmiHeader.biHeight;
+ pVIH->rcSource.right = pVIH->bmiHeader.biWidth;
+ pVIH->rcTarget = pVIH->rcSource;
+ pVIH->dwBitErrorRate = 0;
+ pVIH->AvgTimePerFrame = (LONGLONG)(10000000.0f / fps);
+
+ hr = iConfigCompressedStream( pStreamConfig, pIWMProfile,
+ fIsVBR, dwBitRate, dwQuality,
+ dwSecPerKey, pMediaType );
+ if (FAILED(hr))
+ break;
+
+ hr = pIWMProfile->AddStream( pStreamConfig );
+ if (FAILED(hr))
+ break;
+ }
+ while( wFALSE );
+
+ SAFE_RELEASE( pStreamConfig );
+ SAFE_ARRAYDELETE( pMediaType );
+
+ return( hr );
+}
+
+static HRESULT iConfigUncompressedStream( IWMStreamConfig * pStreamConfig,
+ DWORD dwBitrate,
+ WM_MEDIA_TYPE * pmt )
+{
+ WORD wFALSE = 0;
+ HRESULT hr = S_OK;
+
+ do
+ {
+ // Configure the stream
+
+ hr = pStreamConfig->SetStreamName( L"Video Stream" );
+ if (FAILED(hr))
+ break;
+
+ // Each stream in the profile has to have a unique connection name.
+ // Let's use the stream number to create it.
+
+ WORD wStreamNum = 0;
+ hr = pStreamConfig->GetStreamNumber( &wStreamNum );
+ if (FAILED(hr))
+ break;
+
+ WCHAR pwszConnectionName[10];
+ swprintf( pwszConnectionName, L"Video%d", (DWORD)wStreamNum );
+
+ hr = pStreamConfig->SetConnectionName( pwszConnectionName );
+ if (FAILED(hr))
+ break;
+
+ hr = pStreamConfig->SetBitrate( dwBitrate );
+ if (FAILED(hr))
+ break;
+
+ hr = pStreamConfig->SetBufferWindow( 0 );
+ if (FAILED(hr))
+ break;
+
+ IWMMediaProps * pIWMMediaProps = NULL;
+ hr = pStreamConfig->QueryInterface( IID_IWMMediaProps, (void **) &pIWMMediaProps );
+ if (FAILED(hr))
+ break;
+
+ hr = pIWMMediaProps->SetMediaType( pmt );
+
+ SAFE_RELEASE( pIWMMediaProps );
+
+ if (FAILED(hr))
+ break;
+
+ IWMPropertyVault* pPropertyVault = NULL;
+ hr = pStreamConfig->QueryInterface( IID_IWMPropertyVault, (void**)&pPropertyVault );
+ if (FAILED(hr))
+ break;
+
+ BOOL fFalse = FALSE;
+ hr = pPropertyVault->SetProperty( g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE*)&fFalse, sizeof( BOOL ) );
+
+ SAFE_RELEASE( pPropertyVault );
+
+ hr = S_OK;
+
+ } while( wFALSE );
+
+ return( hr );
+}
+
+static HRESULT iAddUncompressedVideoStream( IWMProfile * pProfile,
+ BITMAPINFOHEADER * bmiHeader,
+ int BitmapInfoSize, int BitmapDataSize,
+ float fps)
+{
+ HRESULT hr = S_OK;
+ WORD wFALSE = 0;
+
+ IWMStreamConfig* pStreamConfig = NULL;
+ WM_MEDIA_TYPE* pMediaType = NULL;
+
+ do
+ {
+ hr = pProfile->CreateNewStream( WMMEDIATYPE_Video, &pStreamConfig );
+ if ( FAILED( hr ) )
+ break;
+
+ DWORD cbVideoInfo = sizeof(WMVIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER) + BitmapInfoSize;
+
+ // Create a new Media Type
+ pMediaType = (WM_MEDIA_TYPE*) new BYTE[ sizeof( WM_MEDIA_TYPE ) + cbVideoInfo ];
+ if ( !pMediaType)
+ {
+ hr = E_OUTOFMEMORY;
+ break;
+ }
+
+ switch (bmiHeader->biBitCount)
+ {
+ case 32:
+ pMediaType->subtype = WMMEDIASUBTYPE_RGB32;
+ break;
+ case 24:
+ pMediaType->subtype = WMMEDIASUBTYPE_RGB24;
+ break;
+ case 8:
+ pMediaType->subtype = WMMEDIASUBTYPE_RGB8;
+ break;
+ }
+
+ pMediaType->majortype = WMMEDIATYPE_Video;
+ pMediaType->bFixedSizeSamples = TRUE;
+ pMediaType->bTemporalCompression = FALSE;
+ pMediaType->lSampleSize = BitmapDataSize;
+ pMediaType->formattype = WMFORMAT_VideoInfo;
+ pMediaType->pUnk = NULL;
+ pMediaType->cbFormat = cbVideoInfo;
+ pMediaType->pbFormat = ( ((BYTE*) pMediaType) + sizeof( WM_MEDIA_TYPE ) ); // Format data is immediately after media type
+
+ WMVIDEOINFOHEADER * pVIH = (WMVIDEOINFOHEADER *) pMediaType->pbFormat;
+
+ pVIH->rcSource.left = 0;
+ pVIH->rcSource.top = 0;
+ pVIH->rcSource.bottom = bmiHeader->biHeight;
+ pVIH->rcSource.right = bmiHeader->biWidth;
+ pVIH->rcTarget = pVIH->rcSource;
+ pVIH->dwBitRate = (DWORD)(BitmapDataSize * fps);
+ pVIH->dwBitErrorRate = 0;
+ pVIH->AvgTimePerFrame = (LONGLONG)(10000000.0f / fps);
+
+ CopyMemory(&pVIH->bmiHeader, bmiHeader, BitmapInfoSize);
+
+ hr = iConfigUncompressedStream( pStreamConfig, pVIH->dwBitRate, pMediaType );
+ if (FAILED(hr))
+ break;
+
+ hr = pProfile->AddStream( pStreamConfig );
+ if (FAILED(hr))
+ break;
+ }
+ while( wFALSE );
+
+ SAFE_RELEASE( pStreamConfig );
+ SAFE_ARRAYDELETE( pMediaType );
+
+ return( hr );
+}
+
+#define WMV_COMPRESS_COUNT 7
+#define WMV_UNCOMPRESS_COUNT 9
+
+static GUID iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+WMV_UNCOMPRESS_COUNT];
+
+static void iInitGuid()
+{
+ iWMVCompSubtypeTable[0] = WMMEDIASUBTYPE_MP43;
+ iWMVCompSubtypeTable[1] = WMMEDIASUBTYPE_MP4S;
+ iWMVCompSubtypeTable[2] = WMMEDIASUBTYPE_WMV1;
+ iWMVCompSubtypeTable[3] = WMMEDIASUBTYPE_MSS1;
+ iWMVCompSubtypeTable[4] = WMMEDIASUBTYPE_WMV2;
+ iWMVCompSubtypeTable[5] = WMMEDIASUBTYPE_MSS2;
+ iWMVCompSubtypeTable[6] = WMMEDIASUBTYPE_WMV3;
+
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+0] = WMMEDIASUBTYPE_RGB555;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+1] = WMMEDIASUBTYPE_RGB24;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+2] = WMMEDIASUBTYPE_RGB32;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+3] = WMMEDIASUBTYPE_I420;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+4] = WMMEDIASUBTYPE_IYUV;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+5] = WMMEDIASUBTYPE_YV12;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+6] = WMMEDIASUBTYPE_YUY2;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+7] = WMMEDIASUBTYPE_UYVY;
+ iWMVCompSubtypeTable[WMV_COMPRESS_COUNT+8] = WMMEDIASUBTYPE_YVYU;
+}
+
+static const char* iWMVCompTable[WMV_COMPRESS_COUNT+1] =
+{
+ "NONE",
+ "MPEG-4v3",
+ "MPEG-4v1",
+ "WMV7",
+ "WMV7Screen",
+ "WMV8",
+ "WMV9Screen",
+ "WMV9"
+};
+
+static const char* iWMFCompFindName(GUID SubType)
+{
+ int i;
+ for(i = 0; i < WMV_COMPRESS_COUNT; i++)
+ {
+ if (SubType == iWMVCompSubtypeTable[i])
+ return iWMVCompTable[i+1];
+ }
+
+ for(; i < WMV_COMPRESS_COUNT+WMV_UNCOMPRESS_COUNT; i++)
+ {
+ if (SubType == iWMVCompSubtypeTable[i])
+ return iWMVCompTable[0];
+ }
+
+ return "Unknown";
+}
+
+static GUID iWMFCompFindSubType(const char* compression)
+{
+ if (compression[0] == 0)
+ return WMMEDIASUBTYPE_WMV3;
+
+ for(int i = 0; i < WMV_COMPRESS_COUNT; i++)
+ {
+ if (imStrEqual(compression, iWMVCompTable[i+1]))
+ return iWMVCompSubtypeTable[i];
+ }
+
+ return WMMEDIASUBTYPE_Base;
+}
+
+class imFileFormatWMV: public imFileFormatBase
+{
+ IWMSyncReader* Reader; // When reading
+ WM_MEDIA_TYPE* MediaType;
+ WORD stream_number;
+ DWORD seekable;
+ int current_frame;
+
+ IWMWriter* Writer; // When writing
+ DWORD input_number;
+ DWORD BitmapDataSize;
+ DWORD BitmapInfoSize;
+
+ float fps;
+ WCHAR wfile_name[4096];
+ IWMHeaderInfo* HeaderInfo;
+ BITMAPINFOHEADER* bmiHeader;
+ unsigned int rmask, gmask, bmask,
+ roff, goff, boff; /* pixel bit mask control when reading 16 and 32 bpp images */
+
+ void ReadPalette(unsigned char* bmp_colors);
+ void WritePalette(unsigned char* bmp_colors);
+ void FixRGB(int bpp);
+ void InitMasks(imDib* dib);
+ void iReadAttrib(imAttribTable* attrib_table);
+ void iWriteAttrib(imAttribTable* attrib_table);
+ void CalcFPS();
+ void SetOutputProps();
+ int SetInputProps();
+ int SetProfile();
+
+public:
+ imFileFormatWMV(const imFormat* _iformat): imFileFormatBase(_iformat) {}
+ ~imFileFormatWMV() {}
+
+ int Open(const char* file_name);
+ int New(const char* file_name);
+ void Close();
+ void* Handle(int index);
+ int ReadImageInfo(int index);
+ int ReadImageData(void* data);
+ int WriteImageInfo();
+ int WriteImageData(void* data);
+};
+
+class imFormatWMV: public imFormat
+{
+public:
+ imFormatWMV()
+ :imFormat("WMV",
+ "Windows Media Video Format",
+ "*.wmv;*.asf;",
+ iWMVCompTable,
+ WMV_COMPRESS_COUNT+1,
+ 1)
+ {}
+ ~imFormatWMV() {}
+
+ imFileFormatBase* Create(void) const { return new imFileFormatWMV(this); }
+ int CanWrite(const char* compression, int color_mode, int data_type) const;
+};
+
+void imFormatRegisterWMV(void)
+{
+ imFormatRegister(new imFormatWMV());
+}
+
+int imFileFormatWMV::Open(const char* file_name)
+{
+ /* initializes COM */
+ CoInitialize(NULL);
+ iInitGuid();
+
+ HRESULT hr = WMCreateSyncReader(NULL, 0, &Reader);
+ if (hr != 0)
+ {
+ CoUninitialize();
+ return IM_ERR_MEM;
+ }
+
+ /* open existing file */
+ MultiByteToWideChar(CP_ACP, 0, file_name, -1, wfile_name, 4096);
+ hr = Reader->Open(wfile_name);
+ if (hr != 0)
+ {
+ Reader->Release();
+ CoUninitialize();
+
+ if (hr == NS_E_FILE_OPEN_FAILED ||
+ hr == NS_E_FILE_NOT_FOUND ||
+ hr == NS_E_INVALID_DATA)
+ return IM_ERR_OPEN;
+ else if (hr == NS_E_UNRECOGNIZED_STREAM_TYPE)
+ return IM_ERR_FORMAT;
+ else
+ return IM_ERR_ACCESS;
+ }
+
+ IWMProfile* pProfile = NULL;
+ Reader->QueryInterface(IID_IWMProfile, (VOID**)&pProfile);
+
+ DWORD stream_count;
+ pProfile->GetStreamCount(&stream_count);
+
+ this->stream_number = (WORD)-1;
+ for (int i = 0; i < (int)stream_count; i++)
+ {
+ IWMStreamConfig* StreamConfig;
+ pProfile->GetStream(i, &StreamConfig);
+
+ GUID StreamType;
+ StreamConfig->GetStreamType(&StreamType);
+
+ if (StreamType == WMMEDIATYPE_Video ||
+ StreamType == WMMEDIATYPE_Image)
+ {
+ hr = StreamConfig->GetStreamNumber(&this->stream_number);
+
+ IWMMediaProps* Props;
+ StreamConfig->QueryInterface(IID_IWMMediaProps, (VOID**)&Props);
+
+ DWORD pcbType;
+ Props->GetMediaType(NULL, &pcbType);
+ MediaType = (WM_MEDIA_TYPE*)malloc(pcbType);
+ Props->GetMediaType(MediaType, &pcbType);
+
+ Props->Release();
+
+ const char* comp_name = iWMFCompFindName(MediaType->subtype);
+ strcpy(this->compression, comp_name);
+ break;
+ }
+
+ StreamConfig->Release();
+ }
+
+ if (this->stream_number == (WORD)-1)
+ {
+ pProfile->Release();
+ Reader->Close();
+ Reader->Release();
+ CoUninitialize();
+ return IM_ERR_DATA;
+ }
+
+ hr = Reader->QueryInterface(IID_IWMHeaderInfo, (VOID**)&HeaderInfo);
+
+ CalcFPS();
+
+ WMT_ATTR_DATATYPE attrib_type;
+ WORD attrib_length;
+ WORD StreamNumber = 0;
+
+ seekable = 0;
+ attrib_length = 4;
+ attrib_type = WMT_TYPE_BOOL;
+ hr = HeaderInfo->GetAttributeByName(&StreamNumber, g_wszWMSeekable,
+ &attrib_type, (BYTE*)&seekable, &attrib_length);
+
+ QWORD num_frame = 0;
+ attrib_length = 8;
+ attrib_type = WMT_TYPE_QWORD;
+ hr = HeaderInfo->GetAttributeByName(&stream_number, g_wszWMNumberOfFrames,
+ &attrib_type, (BYTE*)&num_frame, &attrib_length);
+
+ if (num_frame == 0)
+ {
+ QWORD duration = 0;
+ attrib_length = 8;
+ attrib_type = WMT_TYPE_QWORD;
+ hr = HeaderInfo->GetAttributeByName(&StreamNumber, g_wszWMDuration,
+ &attrib_type, (BYTE*)&duration, &attrib_length);
+
+ num_frame = (int)(((double)(unsigned int)duration * (double)fps) / 10000000.0);
+ }
+
+ this->image_count = (int)num_frame;
+
+ SetOutputProps();
+
+ WMT_STREAM_SELECTION wmtSS = WMT_ON;
+ hr = Reader->SetStreamsSelected(1, &stream_number, &wmtSS);
+ hr = Reader->SetReadStreamSamples(stream_number, FALSE);
+
+ this->bmiHeader = NULL;
+ this->current_frame = 0;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatWMV::New(const char* file_name)
+{
+ /* initializes COM */
+ CoInitialize(NULL);
+ iInitGuid();
+
+ HRESULT hr = WMCreateWriter(NULL, &Writer);
+ if (hr != 0)
+ {
+ CoUninitialize();
+ return IM_ERR_MEM;
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, file_name, -1, wfile_name, 4096);
+
+ Writer->QueryInterface(IID_IWMHeaderInfo, (VOID**)&HeaderInfo);
+
+ this->bmiHeader = NULL;
+ this->current_frame = 0;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatWMV::Close()
+{
+ HeaderInfo->Release();
+
+ if (this->is_new)
+ {
+ free(this->bmiHeader);
+
+ Writer->EndWriting();
+ Writer->Release();
+ }
+ else
+ {
+ free(MediaType);
+
+ Reader->Close();
+ Reader->Release();
+ }
+
+ CoUninitialize();
+}
+
+void* imFileFormatWMV::Handle(int index)
+{
+ if (index == 1)
+ {
+ if (this->is_new)
+ return (void*)this->Writer;
+ else
+ return (void*)this->Reader;
+ }
+ else
+ return NULL;
+}
+
+void imFileFormatWMV::iReadAttrib(imAttribTable* attrib_table)
+{
+ WORD StreamNumber = 0;
+ WORD attrib_list_count = 0;
+ HeaderInfo->GetAttributeCount(StreamNumber, &attrib_list_count);
+
+ WCHAR* attrib_name = NULL;
+ int name_max_size = 0;
+ char* name = NULL;
+ WORD attrib_name_count;
+ WMT_ATTR_DATATYPE attrib_type;
+ BYTE* attrib_data = NULL;
+ WORD attrib_length;
+ int data_max_size = 0;
+ HRESULT hr;
+ int data_type, data_count;
+
+ for (WORD i = 0; i < attrib_list_count; i++)
+ {
+ attrib_name_count = 0;
+ attrib_length = 0;
+
+ hr = HeaderInfo->GetAttributeByIndex(i, &StreamNumber, NULL, &attrib_name_count,
+ &attrib_type, NULL, &attrib_length);
+
+ if (FAILED(hr))
+ continue;
+
+ if (attrib_length == 0)
+ continue;
+
+ if (name_max_size < attrib_name_count)
+ {
+ attrib_name = (WCHAR*)realloc(attrib_name, attrib_name_count*2);
+ name = (char*)realloc(name, attrib_name_count);
+ name_max_size = attrib_name_count;
+ }
+
+ if (data_max_size < attrib_length)
+ {
+ attrib_data = (BYTE*)realloc(attrib_data, attrib_length);
+ data_max_size = attrib_length;
+ }
+
+ HeaderInfo->GetAttributeByIndex(i, &StreamNumber, attrib_name, &attrib_name_count,
+ &attrib_type, attrib_data, &attrib_length);
+
+ WideCharToMultiByte(CP_ACP, 0, attrib_name, attrib_name_count, name, attrib_name_count, NULL, NULL);
+
+ switch (attrib_type)
+ {
+ case WMT_TYPE_BOOL:
+ {
+ DWORD* ddata = (DWORD*)attrib_data;
+ if (*ddata == 0)
+ continue;
+ }
+ case WMT_TYPE_DWORD:
+ data_type = IM_INT;
+ data_count = attrib_length/4;
+ break;
+ case WMT_TYPE_STRING:
+ data_type = IM_BYTE;
+ data_count = attrib_length/2;
+ {
+ WCHAR* wdata = (WCHAR*)attrib_data;
+ CHAR* sdata = (CHAR*)attrib_data;
+ for (int j = 0; j < data_count; j++)
+ {
+ CHAR cvalue;
+ WideCharToMultiByte(CP_ACP, 0, &wdata[j], 1, &cvalue, 1, NULL, NULL);
+ sdata[j] = cvalue;
+ }
+ }
+ break;
+ case WMT_TYPE_BINARY:
+ data_type = IM_BYTE;
+ data_count = attrib_length;
+ break;
+ case WMT_TYPE_QWORD:
+ {
+ data_type = IM_INT;
+ data_count = attrib_length/8;
+ // convert to int in-place
+ QWORD* qdata = (QWORD*)attrib_data;
+ DWORD* ddata = (DWORD*)attrib_data;
+ for (int j = 0; j < data_count; j++)
+ {
+ ddata[j] = (DWORD)qdata[j];
+ }
+ }
+ break;
+ case WMT_TYPE_WORD:
+ data_type = IM_USHORT;
+ data_count = attrib_length/2;
+ break;
+ default:
+ continue;
+ }
+
+ attrib_table->Set(name, data_type, data_count, attrib_data);
+ }
+
+ if (name) free(name);
+ if (attrib_name) free(attrib_name);
+ if (attrib_data) free(attrib_data);
+}
+
+static int iAttribSet(void* user_data, int index, const char* name, int data_type, int data_count, const void* data)
+{
+ (void)index;
+ WORD StreamNumber = 0;
+ IWMHeaderInfo* HeaderInfo = (IWMHeaderInfo*)user_data;
+
+ WCHAR wName[50];
+ WMT_ATTR_DATATYPE Type;
+ BYTE* Value = NULL;
+ WORD ValueSize = 0;
+
+ MultiByteToWideChar(CP_ACP, 0, name, -1, wName, 50);
+
+ switch(data_type)
+ {
+ case IM_BYTE:
+ if (imStrCheck(data, data_count))
+ Type = WMT_TYPE_STRING;
+ else
+ Type = WMT_TYPE_BINARY;
+ break;
+ case IM_USHORT:
+ Type = WMT_TYPE_WORD;
+ break;
+ case IM_INT:
+ Type = WMT_TYPE_DWORD;
+ break;
+ default:
+ return 1;
+ }
+
+ switch (Type)
+ {
+ case WMT_TYPE_BOOL:
+ case WMT_TYPE_DWORD:
+ ValueSize = (WORD)(data_count*4);
+ break;
+ case WMT_TYPE_STRING:
+ ValueSize = (WORD)(data_count*2);
+ Value = (BYTE*)malloc(ValueSize);
+ MultiByteToWideChar(CP_ACP, 0, (char*)data, data_count, (WCHAR*)Value, data_count);
+ break;
+ case WMT_TYPE_BINARY:
+ ValueSize = (WORD)data_count;
+ break;
+ case WMT_TYPE_QWORD:
+ {
+ ValueSize = (WORD)(data_count*8);
+ Value = (BYTE*)malloc(ValueSize);
+
+ QWORD* qdata = (QWORD*)Value;
+ int* idata = (int*)data;
+ for (int j = 0; j < data_count; j++)
+ {
+ qdata[j] = (QWORD)idata[j];
+ }
+ }
+ break;
+ case WMT_TYPE_WORD:
+ ValueSize = (WORD)(data_count*2);
+ break;
+ }
+
+ if (Value)
+ {
+ HeaderInfo->SetAttribute(StreamNumber, wName, Type,
+ Value, ValueSize);
+ free(Value);
+ }
+ else
+ HeaderInfo->SetAttribute(StreamNumber, wName, Type,
+ (BYTE*)data, ValueSize);
+ return 1;
+}
+
+void imFileFormatWMV::iWriteAttrib(imAttribTable* attrib_table)
+{
+ attrib_table->ForEach((void*)HeaderInfo, iAttribSet);
+}
+
+void imFileFormatWMV::CalcFPS()
+{
+ LONGLONG AvgTimePerFrame = 0;
+
+ if (MediaType->formattype == WMFORMAT_VideoInfo)
+ {
+ WMVIDEOINFOHEADER* info_header = (WMVIDEOINFOHEADER*)MediaType->pbFormat;
+ bmiHeader = &info_header->bmiHeader;
+ AvgTimePerFrame = info_header->AvgTimePerFrame;
+ }
+ else if (MediaType->formattype == WMFORMAT_MPEG2Video)
+ {
+ WMVIDEOINFOHEADER2* info_header = (WMVIDEOINFOHEADER2*)MediaType->pbFormat;
+ bmiHeader = &info_header->bmiHeader;
+ AvgTimePerFrame = info_header->AvgTimePerFrame;
+ }
+
+ WMT_ATTR_DATATYPE attrib_type;
+ WORD attrib_length;
+
+ DWORD frame_rate = 0;
+ attrib_length = 4;
+ HeaderInfo->GetAttributeByName(&stream_number, g_wszWMVideoFrameRate, // V9 Only
+ &attrib_type, (BYTE*)&frame_rate, &attrib_length);
+
+ fps = (float)frame_rate;
+ if (frame_rate == 0)
+ {
+ if (AvgTimePerFrame == 0)
+ {
+ fps = 15; // default value
+ }
+ else
+ {
+ fps = 10000000.0f / (float)AvgTimePerFrame;
+
+ int ifps = (int)(fps * 100);
+ if (ifps == 2997 || ifps == 2996 || ifps == 2998)
+ fps = (30.0f * 1000.0f) / 1001.0f;
+ else if (ifps == 2397 || ifps == 2396 || ifps == 2398)
+ fps = (24.0f * 1000.0f) / 1001.0f;
+ else if (ifps == 2400)
+ fps = 24.0f;
+ else if (ifps == 3000)
+ fps = 30.0f;
+ }
+ }
+}
+
+void imFileFormatWMV::SetOutputProps()
+{
+ DWORD output_number;
+ Reader->GetOutputNumberForStream(stream_number, &output_number);
+
+ DWORD format_count;
+ Reader->GetOutputFormatCount(output_number, &format_count);
+
+ for(DWORD f = 0; f < format_count; f++)
+ {
+ IWMOutputMediaProps* Props;
+ Reader->GetOutputFormat(output_number, f, &Props);
+
+ DWORD pcbType;
+ Props->GetMediaType(NULL, &pcbType);
+ WM_MEDIA_TYPE* mt = (WM_MEDIA_TYPE*)malloc(pcbType);
+ Props->GetMediaType(mt, &pcbType);
+
+ if (mt->subtype == WMMEDIASUBTYPE_RGB24 ||
+ mt->subtype == WMMEDIASUBTYPE_RGB8)
+ {
+ Reader->SetOutputProps(output_number, Props);
+ Props->Release();
+ free(mt);
+ return;
+ }
+
+ Props->Release();
+ free(mt);
+ }
+}
+
+int imFileFormatWMV::SetInputProps()
+{
+ DWORD input_count;
+ Writer->GetInputCount(&input_count);
+
+ GUID guidInputType;
+ IWMInputMediaProps* Props = NULL;
+
+ input_number = (DWORD)-1;
+ for(DWORD i = 0; i < input_count; i++)
+ {
+ Writer->GetInputProps(i, &Props);
+
+ Props->GetType(&guidInputType);
+
+ if(guidInputType == WMMEDIATYPE_Video)
+ {
+ input_number = i;
+ break;
+ }
+
+ Props->Release();
+ }
+
+ if (input_number == (DWORD)-1)
+ return 0;
+
+ DWORD cbVideoInfo = sizeof(WMVIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER) + this->BitmapInfoSize;
+ WMVIDEOINFOHEADER* pVideoInfo = (WMVIDEOINFOHEADER*)new BYTE[cbVideoInfo];
+
+ pVideoInfo->rcSource.left = 0;
+ pVideoInfo->rcSource.top = 0;
+ pVideoInfo->rcSource.bottom = this->bmiHeader->biHeight;
+ pVideoInfo->rcSource.right = this->bmiHeader->biWidth;
+ pVideoInfo->rcTarget = pVideoInfo->rcSource;
+ pVideoInfo->dwBitRate = (DWORD)(this->BitmapDataSize * fps);
+ pVideoInfo->dwBitErrorRate = 0;
+ pVideoInfo->AvgTimePerFrame = (LONGLONG)(10000000.0f / fps);
+
+ CopyMemory(&(pVideoInfo->bmiHeader), this->bmiHeader, BitmapInfoSize);
+
+ WM_MEDIA_TYPE mt;
+ mt.majortype = WMMEDIATYPE_Video;
+ mt.bFixedSizeSamples = TRUE;
+ mt.bTemporalCompression = FALSE;
+ mt.lSampleSize = BitmapDataSize;
+ mt.formattype = WMFORMAT_VideoInfo;
+ mt.pUnk = NULL;
+ mt.cbFormat = cbVideoInfo;
+ mt.pbFormat = (BYTE*)pVideoInfo;
+
+ switch (this->bmiHeader->biBitCount)
+ {
+ case 32:
+ mt.subtype = WMMEDIASUBTYPE_RGB32;
+ break;
+ case 24:
+ mt.subtype = WMMEDIASUBTYPE_RGB24;
+ break;
+ case 8:
+ mt.subtype = WMMEDIASUBTYPE_RGB8;
+ break;
+ }
+
+ Props->SetMediaType(&mt);
+
+ HRESULT hr = Writer->SetInputProps(input_number, Props);
+ Props->Release();
+ free(pVideoInfo);
+
+ if (FAILED(hr))
+ return 0;
+
+ return 1;
+}
+
+int imFileFormatWMV::SetProfile()
+{
+ HRESULT hr;
+
+ IWMProfileManager* ProfileManager = NULL;
+ WMCreateProfileManager(&ProfileManager);
+
+ IWMProfile* Profile = NULL;
+ hr = ProfileManager->CreateEmptyProfile(WMT_VER_9_0, &Profile);
+ if (FAILED(hr))
+ {
+ ProfileManager->Release();
+ return 0;
+ }
+
+ if (imStrEqual(this->compression, "NONE"))
+ {
+ hr = iAddUncompressedVideoStream(Profile,
+ this->bmiHeader,
+ this->BitmapInfoSize, this->BitmapDataSize, this->fps);
+ }
+ else
+ {
+ DWORD dwBitRate = 2400*1000;
+ const void* attrib_data = AttribTable()->Get("DataRate");
+ if (attrib_data)
+ dwBitRate = (*(int*)attrib_data) * 1000;
+
+ DWORD dwQuality = 50;
+ attrib_data = AttribTable()->Get("WMFQuality");
+ if (attrib_data)
+ dwQuality = *(int*)attrib_data;
+
+ DWORD dwSecPerKey = 5000;
+ attrib_data = AttribTable()->Get("MaxKeyFrameTime");
+ if (attrib_data)
+ dwSecPerKey = *(int*)attrib_data;
+
+ BOOL fIsVBR = FALSE; // CBR is the default
+ attrib_data = AttribTable()->Get("VBR");
+ if (attrib_data)
+ fIsVBR = *(int*)attrib_data;
+
+ GUID subtype = iWMFCompFindSubType(this->compression);
+ if (subtype == WMMEDIASUBTYPE_Base)
+ {
+ Profile->Release();
+ ProfileManager->Release();
+ return 0;
+ }
+
+ hr = iAddCompressedVideoStream(ProfileManager, Profile, subtype,
+ this->bmiHeader, this->fps,
+ fIsVBR, dwBitRate, dwQuality, dwSecPerKey);
+ }
+
+ hr = Writer->SetProfile(Profile);
+ Profile->Release();
+ ProfileManager->Release();
+
+ if (FAILED(hr))
+ return 0;
+
+ return 1;
+}
+
+int imFileFormatWMV::ReadImageInfo(int index)
+{
+ if (this->seekable && this->current_frame != index)
+ {
+ HRESULT hr = Reader->SetRangeByFrame(stream_number, index, 0);
+ this->current_frame = index;
+
+ if (hr == NS_E_INVALID_REQUEST)
+ {
+ QWORD start_time = (QWORD)(index * (10000000.0f / fps));
+ hr = Reader->SetRange(start_time, 0);
+ }
+
+ if (hr != S_OK)
+ return IM_ERR_ACCESS;
+ }
+
+ if (this->bmiHeader != NULL)
+ return IM_ERR_NONE;
+
+ imAttribTable* attrib_table = AttribTable();
+
+ /* must clear the attribute list, because it can have multiple images and
+ has many attributes that may exists only for specific images. */
+ attrib_table->RemoveAll();
+ imFileSetBaseAttributes(this);
+
+ if (MediaType->formattype == WMFORMAT_VideoInfo)
+ {
+ WMVIDEOINFOHEADER* info_header = (WMVIDEOINFOHEADER*)MediaType->pbFormat;
+ bmiHeader = &info_header->bmiHeader;
+
+ if (info_header->dwBitRate)
+ {
+ int data_rate = info_header->dwBitRate/1000;
+ attrib_table->Set("DataRate", IM_INT, 1, &data_rate);
+ }
+ }
+ else if (MediaType->formattype == WMFORMAT_MPEG2Video)
+ {
+ WMVIDEOINFOHEADER2* info_header = (WMVIDEOINFOHEADER2*)MediaType->pbFormat;
+ bmiHeader = &info_header->bmiHeader;
+
+ if (info_header->dwBitRate)
+ {
+ int data_rate = info_header->dwBitRate/1000;
+ attrib_table->Set("DataRate", IM_INT, 1, &data_rate);
+ }
+
+ if (info_header->dwInterlaceFlags)
+ {
+ int int_value = 1;
+ attrib_table->Set("Interlaced", IM_INT, 1, &int_value);
+
+ if (info_header->dwInterlaceFlags & AMINTERLACE_1FieldPerSample)
+ int_value = 1;
+ else
+ int_value = 2;
+
+ attrib_table->Set("FieldsPerSample", IM_INT, 1, &int_value);
+
+ if (info_header->dwInterlaceFlags & AMINTERLACE_Field1First)
+ int_value = 1;
+ else
+ int_value = 2;
+
+ attrib_table->Set("FirstField", IM_INT, 1, &int_value);
+
+ // OBS: The top field in PAL is field 1, and the top field in NTSC is field 2
+ }
+
+ if (info_header->dwPictAspectRatioX)
+ attrib_table->Set("XAspectRatio", IM_INT, 1, &info_header->dwPictAspectRatioX);
+ if (info_header->dwPictAspectRatioY)
+ attrib_table->Set("YAspectRatio", IM_INT, 1, &info_header->dwPictAspectRatioY);
+ }
+ else
+ return IM_ERR_DATA;
+
+ attrib_table->Set("FPS", IM_FLOAT, 1, &fps);
+
+ int top_down = 0;
+ if (bmiHeader->biHeight < 0)
+ top_down = 1;
+
+ this->width = bmiHeader->biWidth;
+ this->height = top_down? -bmiHeader->biHeight: bmiHeader->biHeight;
+
+ int bpp = bmiHeader->biBitCount;
+
+ this->file_data_type = IM_BYTE;
+
+ if (bpp > 8)
+ {
+ this->file_color_mode = IM_RGB;
+ this->file_color_mode |= IM_PACKED;
+ }
+ else
+ {
+ this->palette_count = 1 << bpp;
+ this->file_color_mode = IM_MAP;
+ }
+
+ if (bpp < 8)
+ this->convert_bpp = bpp;
+
+ if (bpp == 32)
+ this->file_color_mode |= IM_ALPHA;
+
+ if (top_down)
+ this->file_color_mode |= IM_TOPDOWN;
+
+ if (bpp <= 8)
+ {
+ /* updates the palette_count based on the number of colors used */
+ if (bmiHeader->biClrUsed != 0 &&
+ (int)bmiHeader->biClrUsed < this->palette_count)
+ this->palette_count = bmiHeader->biClrUsed;
+
+ ReadPalette((unsigned char*)(bmiHeader + 1));
+ }
+
+ this->line_buffer_extra = 4; // room enough for padding
+
+ iReadAttrib(attrib_table);
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatWMV::WriteImageInfo()
+{
+ if (this->bmiHeader)
+ {
+ if (this->bmiHeader->biWidth != width || this->bmiHeader->biHeight != height ||
+ imColorModeSpace(file_color_mode) != imColorModeSpace(user_color_mode))
+ return IM_ERR_DATA;
+
+ return IM_ERR_NONE; // parameters can be set only once
+ }
+
+ // force bottom up orientation
+ this->file_data_type = IM_BYTE;
+ this->file_color_mode = imColorModeSpace(this->user_color_mode);
+
+ int bpp;
+ if (this->file_color_mode == IM_RGB)
+ {
+ this->file_color_mode |= IM_PACKED;
+ bpp = 24;
+
+ if (imColorModeHasAlpha(this->user_color_mode))
+ {
+ this->file_color_mode |= IM_ALPHA;
+ bpp = 32;
+
+ this->rmask = 0x00FF0000;
+ this->roff = 16;
+
+ this->gmask = 0x0000FF00;
+ this->goff = 8;
+
+ this->bmask = 0x000000FF;
+ this->boff = 0;
+ }
+ }
+ else
+ bpp = 8;
+
+ this->line_buffer_extra = 4; // room enough for padding
+
+ imAttribTable* attrib_table = AttribTable();
+
+ const void* attrib_data = attrib_table->Get("FPS");
+ if (attrib_data)
+ fps = *(float*)attrib_data;
+ else
+ fps = 15;
+
+ this->BitmapDataSize = this->height * imFileLineSizeAligned(this->width, bpp, 4);
+
+ DWORD biClrUsed = bpp > 8? 0: this->palette_count;
+ this->BitmapInfoSize = sizeof(BITMAPINFOHEADER) + biClrUsed * sizeof(RGBQUAD);
+
+ this->bmiHeader = (BITMAPINFOHEADER*)malloc(this->BitmapInfoSize);
+ this->bmiHeader->biSize = sizeof(BITMAPINFOHEADER);
+ this->bmiHeader->biWidth = this->width;
+ this->bmiHeader->biHeight = this->height;
+ this->bmiHeader->biPlanes = 1;
+ this->bmiHeader->biBitCount = (WORD)bpp;
+ this->bmiHeader->biCompression = BI_RGB;
+ this->bmiHeader->biSizeImage = this->BitmapDataSize;
+ this->bmiHeader->biXPelsPerMeter = 0;
+ this->bmiHeader->biYPelsPerMeter = 0;
+ this->bmiHeader->biClrUsed = biClrUsed;
+ this->bmiHeader->biClrImportant = 0;
+
+ if (this->bmiHeader->biBitCount <= 8)
+ WritePalette((unsigned char*)(this->bmiHeader + 1));
+
+ if (!SetProfile())
+ return IM_ERR_COMPRESS;
+
+ if (!SetInputProps())
+ return IM_ERR_ACCESS;
+
+ HRESULT hr = Writer->SetOutputFilename(wfile_name);
+ if(FAILED(hr))
+ return IM_ERR_ACCESS;
+
+ iWriteAttrib(attrib_table);
+
+ hr = Writer->BeginWriting();
+ if(FAILED(hr))
+ return IM_ERR_ACCESS;
+
+ return IM_ERR_NONE;
+}
+
+void imFileFormatWMV::ReadPalette(unsigned char* bmp_colors)
+{
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * 4;
+ this->palette[c] = imColorEncode(bmp_colors[i + 2],
+ bmp_colors[i + 1],
+ bmp_colors[i]);
+ }
+}
+
+void imFileFormatWMV::WritePalette(unsigned char* bmp_colors)
+{
+ /* convert the color map to the IM format */
+ for (int c = 0; c < this->palette_count; c++)
+ {
+ int i = c * 4;
+ imColorDecode(&bmp_colors[i + 2], &bmp_colors[i + 1], &bmp_colors[i], this->palette[c]);
+ bmp_colors[i + 3] = 0;
+ }
+}
+
+void imFileFormatWMV::InitMasks(imDib* dib)
+{
+ if (dib->bmih->biCompression == BI_BITFIELDS)
+ {
+ unsigned int Mask;
+ unsigned int *PalMask = (unsigned int*)dib->bmic;
+
+ this->roff = 0;
+ this->rmask = Mask = PalMask[0];
+ while (!(Mask & 0x01) && (Mask != 0))
+ {Mask >>= 1; this->roff++;}
+
+ this->goff = 0;
+ this->gmask = Mask = PalMask[1];
+ while (!(Mask & 0x01) && (Mask != 0))
+ {Mask >>= 1; this->goff++;}
+
+ this->boff = 0;
+ this->bmask = Mask = PalMask[2];
+ while (!(Mask & 0x01) && (Mask != 0))
+ {Mask >>= 1; this->boff++;}
+ }
+ else
+ {
+ if (dib->bmih->biBitCount == 16)
+ {
+ this->rmask = 0x7C00;
+ this->roff = 10;
+
+ this->gmask = 0x03E0;
+ this->goff = 5;
+
+ this->bmask = 0x001F;
+ this->boff = 0;
+ }
+ else
+ {
+ this->rmask = 0x00FF0000;
+ this->roff = 16;
+
+ this->gmask = 0x0000FF00;
+ this->goff = 8;
+
+ this->bmask = 0x000000FF;
+ this->boff = 0;
+ }
+ }
+}
+
+void imFileFormatWMV::FixRGB(int bpp)
+{
+ int x;
+
+ switch (bpp)
+ {
+ case 16:
+ {
+ /* inverts the WORD values if not intel */
+ if (imBinCPUByteOrder() == IM_BIGENDIAN)
+ imBinSwapBytes2(this->line_buffer, this->width);
+
+ imushort* word_data = (imushort*)this->line_buffer;
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+
+ // from end to start
+ for (x = this->width-1; x >= 0; x--)
+ {
+ imushort word_value = word_data[x];
+ int c = x*3;
+ byte_data[c] = (imbyte)((((rmask & word_value) >> roff) * 255) / (rmask >> roff));
+ byte_data[c+1] = (imbyte)((((gmask & word_value) >> goff) * 255) / (gmask >> goff));
+ byte_data[c+2] = (imbyte)((((bmask & word_value) >> boff) * 255) / (bmask >> boff));
+ }
+ }
+ break;
+ case 32:
+ {
+ unsigned int* dword_data = (unsigned int*)this->line_buffer;
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+
+ for (x = 0; x < this->width; x++)
+ {
+ unsigned int dword_value = dword_data[x];
+ int c = x*3;
+ byte_data[c] = (imbyte)((rmask & dword_value) >> roff);
+ byte_data[c+1] = (imbyte)((gmask & dword_value) >> goff);
+ byte_data[c+2] = (imbyte)((bmask & dword_value) >> boff);
+ byte_data[c+3] = (imbyte)((0xFF000000 & dword_value) >> 24);
+ }
+ }
+ break;
+ default: // 24
+ {
+ imbyte* byte_data = (imbyte*)this->line_buffer;
+ for (x = 0; x < this->width; x++)
+ {
+ int c = x*3;
+ imbyte temp = byte_data[c]; // swap R and B
+ byte_data[c] = byte_data[c+2];
+ byte_data[c+2] = temp;
+ }
+ }
+ break;
+ }
+}
+
+int imFileFormatWMV::ReadImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Reading WMV Frame...");
+
+ INSSBuffer* pSample = NULL;
+
+ {
+ QWORD cnsSampleTime = 0; // All will be ignored
+ QWORD cnsDuration = 0;
+ DWORD dwFlags = 0;
+ WORD wStreamNum = 0;
+ DWORD dwOutputNum = 0;
+ HRESULT hr;
+
+ hr = Reader->GetNextSample(stream_number, &pSample, &cnsSampleTime,
+ &cnsDuration, &dwFlags,
+ &dwOutputNum, &wStreamNum);
+
+ if (FAILED(hr))
+ return IM_ERR_ACCESS;
+ }
+
+ imbyte* dib_bits = NULL;
+ pSample->GetBuffer(&dib_bits);
+ if (!dib_bits)
+ {
+ pSample->Release();
+ return IM_ERR_MEM;
+ }
+
+ imDib* dib = imDibCreateReference((imbyte*)this->bmiHeader, dib_bits);
+
+ if (dib->bmih->biBitCount == 16 || dib->bmih->biBitCount == 32)
+ InitMasks(dib);
+ else if (dib->bmih->biBitCount <= 8)
+ {
+ this->palette_count = dib->palette_count;
+ ReadPalette((unsigned char*)dib->bmic);
+ }
+
+ for (int row = 0; row < this->height; row++)
+ {
+ CopyMemory(this->line_buffer, dib_bits, dib->line_size);
+ dib_bits += dib->line_size;
+
+ if (dib->bmih->biBitCount > 8)
+ FixRGB(dib->bmih->biBitCount);
+
+ imFileLineBufferRead(this, data, row, 0);
+
+ if (!imCounterInc(this->counter))
+ {
+ imDibDestroy(dib);
+ dib = NULL;
+ pSample->Release();
+ return IM_ERR_COUNTER;
+ }
+ }
+
+ imDibDestroy(dib);
+ pSample->Release();
+ this->current_frame++;
+
+ return IM_ERR_NONE;
+}
+
+int imFileFormatWMV::WriteImageData(void* data)
+{
+ imCounterTotal(this->counter, this->height, "Writing WMV Frame...");
+
+ INSSBuffer* pSample = NULL;
+ Writer->AllocateSample(BitmapDataSize, &pSample);
+
+ imbyte* dib_bits = NULL;
+ if (pSample) pSample->GetBuffer(&dib_bits);
+ if (!dib_bits || !pSample)
+ {
+ if (pSample) pSample->Release();
+ return IM_ERR_MEM;
+ }
+
+ imDib* dib = imDibCreateReference((imbyte*)this->bmiHeader, dib_bits);
+ if (dib->bmih->biBitCount <= 8)
+ WritePalette((unsigned char*)dib->bmic);
+
+ for (int row = 0; row < this->height; row++)
+ {
+ imFileLineBufferWrite(this, data, row, 0);
+
+ if (dib->bmih->biBitCount > 8)
+ FixRGB(dib->bmih->biBitCount);
+
+ CopyMemory(dib_bits, this->line_buffer, dib->line_size);
+ dib_bits += dib->line_size;
+
+ if (!imCounterInc(this->counter))
+ return IM_ERR_COUNTER;
+ }
+
+ QWORD VideoTime = (QWORD)(this->image_count * (10000000.0f / fps));
+
+ HRESULT hr = Writer->WriteSample(input_number,
+ VideoTime,
+ 0,
+ pSample);
+ if (hr != 0)
+ return IM_ERR_ACCESS;
+
+ imDibDestroy(dib);
+ pSample->Release();
+ this->image_count++;
+
+ return IM_ERR_NONE;
+}
+
+int imFormatWMV::CanWrite(const char* compression, int color_mode, int data_type) const
+{
+ (void)compression;
+
+ int color_space = imColorModeSpace(color_mode);
+
+ if (color_space == IM_YCBCR || color_space == IM_LAB ||
+ color_space == IM_LUV || color_space == IM_XYZ ||
+ color_space == IM_CMYK)
+ return IM_ERR_DATA;
+
+ if (data_type != IM_BYTE)
+ return IM_ERR_DATA;
+
+ return IM_ERR_NONE;
+}
diff --git a/im/src/im_image.cpp b/im/src/im_image.cpp
new file mode 100755
index 0000000..1fb993d
--- /dev/null
+++ b/im/src/im_image.cpp
@@ -0,0 +1,695 @@
+/** \file
+ * \brief Image Manipulation
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_image.cpp,v 1.4 2009/08/13 22:34:25 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <assert.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+#include "im_attrib.h"
+#include "im_file.h"
+
+
+int imImageCheckFormat(int color_mode, int data_type)
+{
+ if ((imColorModeSpace(color_mode) == IM_MAP || imColorModeSpace(color_mode) == IM_BINARY) &&
+ (data_type != IM_BYTE))
+ return 0;
+
+ return 1;
+}
+
+int imImagePixelOffset(int is_packed, int width, int height, int depth, int col, int row, int plane)
+{
+ if (is_packed)
+ return row*width*depth + col*depth + plane;
+ else
+ return plane*width*height + row*width + col;
+}
+
+int imImageDataSize(int width, int height, int color_mode, int data_type)
+{
+ return width * height * imColorModeDepth(color_mode) * imDataTypeSize(data_type);
+}
+
+int imImageLineCount(int width, int color_mode)
+{
+ if (imColorModeIsPacked(color_mode))
+ return width*imColorModeDepth(color_mode);
+ else
+ return width;
+}
+
+int imImageLineSize(int width, int color_mode, int data_type)
+{
+ return imImageLineCount(width, color_mode) * imDataTypeSize(data_type);
+}
+
+static void iImageInit(imImage* image, int width, int height, int color_space, int data_type, int has_alpha)
+{
+ assert(width>0);
+ assert(height>0);
+ assert(color_space >= IM_RGB && color_space <= IM_XYZ);
+ assert(data_type >= IM_BYTE && data_type <= IM_CFLOAT);
+
+ image->width = width;
+ image->height = height;
+ image->color_space = color_space;
+ image->data_type = data_type;
+ image->has_alpha = has_alpha;
+
+ image->depth = imColorModeDepth(color_space);
+ image->line_size = image->width * imDataTypeSize(data_type);
+ image->plane_size = image->line_size * image->height;
+ image->size = image->plane_size * image->depth;
+ image->count = image->width * image->height;
+
+ int depth = image->depth+1; // add room for an alpha plane pointer, even if does not have alpha now.
+
+ if (image->data)
+ {
+ /* if reallocating, preserve the data buffer */
+ void* data0 = image->data[0];
+
+ free(image->data);
+ image->data = (void**)malloc(depth * sizeof(void*));
+
+ image->data[0] = data0;
+ }
+ else
+ image->data = (void**)malloc(depth * sizeof(void*));
+}
+
+imImage* imImageInit(int width, int height, int color_space, int data_type, void* data_buffer, long* palette, int palette_count)
+{
+ if (!imImageCheckFormat(color_space, data_type))
+ return NULL;
+
+ imImage* image = (imImage*)malloc(sizeof(imImage));
+ image->data = 0;
+
+ iImageInit(image, width, height, color_space, data_type, 0);
+
+ if (data_buffer)
+ {
+ for (int d = 0; d < image->depth; d++)
+ image->data[d] = (imbyte*)data_buffer + d*image->plane_size;
+ }
+
+ if (imColorModeDepth(color_space) == 1)
+ {
+ image->palette = palette;
+ image->palette_count = palette_count;
+ }
+ else
+ {
+ image->palette = NULL;
+ image->palette_count = 0;
+ }
+
+ image->attrib_table = new imAttribTable(599);
+
+ return image;
+}
+
+imImage* imImageCreate(int width, int height, int color_space, int data_type)
+{
+ imImage* image = imImageInit(width, height, color_space, data_type, NULL, NULL, 0);
+ if (!image) return NULL;
+
+ /* palette is available to BINARY, MAP and GRAY */
+ if (imColorModeDepth(color_space) == 1)
+ {
+ image->palette = (long*)malloc(256*sizeof(long));
+
+ if (image->color_space == IM_BINARY)
+ {
+ image->palette_count = 2;
+ image->palette[0] = imColorEncode(0, 0, 0);
+ image->palette[1] = imColorEncode(255, 255, 255);
+ }
+ else
+ {
+ image->palette_count = 256;
+ for (int i = 0; i < 256; i++)
+ image->palette[i] = imColorEncode((imbyte)i, (imbyte)i, (imbyte)i);
+ }
+ }
+
+ /* allocate data buffer */
+ image->data[0] = malloc(image->size);
+ if (!image->data[0])
+ {
+ imImageDestroy(image);
+ return NULL;
+ }
+
+ /* initialize data plane pointers */
+ for (int d = 1; d < image->depth; d++)
+ image->data[d] = (imbyte*)(image->data[0]) + d*image->plane_size;
+
+ imImageClear(image);
+
+ return image;
+}
+
+imImage* imImageCreateBased(const imImage* image, int width, int height, int color_space, int data_type)
+{
+ assert(image);
+
+ if (width <= 0) width = image->width;
+ if (height <= 0) height = image->height;
+ if (color_space < 0) color_space = image->color_space;
+ if (data_type < 0) data_type = image->data_type;
+
+ imImage* new_image = imImageCreate(width, height, color_space, data_type);
+ imImageCopyAttributes(image, new_image);
+
+ if (image->has_alpha)
+ imImageAddAlpha(new_image);
+
+ return new_image;
+}
+
+void imImageAddAlpha(imImage* image)
+{
+ assert(image);
+
+ if (image->has_alpha)
+ return;
+
+ unsigned char* new_data = (unsigned char*)realloc(image->data[0], image->size+image->plane_size);
+ if (!new_data)
+ return;
+
+ image->data[0] = new_data;
+ for (int d = 1; d < image->depth+1; d++)
+ image->data[d] = (imbyte*)(image->data[0]) + d*image->plane_size;
+
+ memset(image->data[image->depth], 0, image->plane_size);
+
+ image->has_alpha = IM_ALPHA;
+}
+
+void imImageReshape(imImage* image, int width, int height)
+{
+ assert(image);
+
+ int old_size = image->size,
+ old_width = width,
+ old_height = height;
+
+ iImageInit(image, width, height, image->color_space, image->data_type, image->has_alpha);
+
+ if (old_size < image->size)
+ {
+ void* data0 = realloc(image->data[0], image->has_alpha? image->size+image->plane_size: image->size);
+ if (!data0) // if failed restore the previous size
+ iImageInit(image, old_width, old_height, image->color_space, image->data_type, image->has_alpha);
+ else
+ image->data[0] = data0;
+ }
+
+ /* initialize data plane pointers */
+ int depth = image->has_alpha? image->depth+1: image->depth;
+ for (int d = 1; d < depth; d++)
+ image->data[d] = (imbyte*)image->data[0] + d*image->plane_size;
+}
+
+void imImageDestroy(imImage* image)
+{
+ assert(image);
+
+ imAttribTable* attrib_table = (imAttribTable*)image->attrib_table;
+ delete attrib_table;
+
+ if (image->data[0])
+ free(image->data[0]);
+
+ if (image->palette)
+ free(image->palette);
+
+ free(image->data);
+
+ // This will help detect invalid image usage after destroy.
+ memset(image, 0, sizeof(imImage));
+
+ free(image);
+}
+
+void imImageClear(imImage* image)
+{
+ assert(image);
+
+ if ((image->color_space == IM_YCBCR || image->color_space == IM_LAB || image->color_space == IM_LUV) &&
+ (image->data_type == IM_BYTE || image->data_type == IM_USHORT))
+ {
+ memset(image->data[0], 0, image->plane_size);
+
+ if (image->data_type == IM_BYTE)
+ {
+ imbyte* usdata = (imbyte*)image->data[1];
+ for (int i = 0; i < 2*image->count; i++)
+ *usdata++ = 128;
+ }
+ else
+ {
+ imushort* usdata = (imushort*)image->data[1];
+ for (int i = 0; i < 2*image->count; i++)
+ *usdata++ = 32768;
+ }
+ }
+ else
+ memset(image->data[0], 0, image->size);
+
+ if (image->has_alpha)
+ memset(image->data[image->depth], 0, image->plane_size);
+}
+
+int imImageIsBitmap(const imImage* image)
+{
+ assert(image);
+ return imColorModeIsBitmap(image->color_space, image->data_type);
+}
+
+void imImageCopy(const imImage* src_image, imImage* dst_image)
+{
+ assert(src_image);
+ assert(dst_image);
+
+ imImageCopyData(src_image, dst_image);
+
+ if (dst_image != src_image)
+ imImageCopyAttributes(src_image, dst_image);
+}
+
+void imImageCopyData(const imImage* src_image, imImage* dst_image)
+{
+ assert(src_image);
+ assert(dst_image);
+ assert(imImageMatch(src_image, dst_image));
+
+ if (dst_image != src_image)
+ {
+ memcpy(dst_image->data[0], src_image->data[0], (src_image->has_alpha && dst_image->has_alpha)? src_image->size+src_image->plane_size: src_image->size);
+ }
+}
+
+imImage* imImageDuplicate(const imImage* image)
+{
+ assert(image);
+
+ imImage* new_image = imImageCreate(image->width, image->height, image->color_space, image->data_type);
+ if (!new_image)
+ return NULL;
+
+ if (image->has_alpha)
+ imImageAddAlpha(new_image);
+
+ imImageCopy(image, new_image);
+
+ return new_image;
+}
+
+imImage* imImageClone(const imImage* image)
+{
+ assert(image);
+
+ imImage* new_image = imImageCreate(image->width, image->height, image->color_space, image->data_type);
+ if (!new_image)
+ return NULL;
+
+ if (image->has_alpha)
+ imImageAddAlpha(new_image);
+
+ imImageCopyAttributes(image, new_image);
+
+ return new_image;
+}
+
+void imImageSetAttribute(const imImage* image, const char* attrib, int data_type, int count, const void* data)
+{
+ assert(image);
+ assert(attrib);
+ imAttribTable* attrib_table = (imAttribTable*)image->attrib_table;
+ if (data)
+ {
+ if (count == -1 && data_type == IM_BYTE) // Data is zero terminated like a string
+ count = strlen((char*)data)+1;
+
+ attrib_table->Set(attrib, data_type, count, data);
+ }
+ else if (count == 0)
+ attrib_table->UnSet(attrib);
+ else
+ attrib_table->Set(attrib, data_type, count, NULL);
+}
+
+const void* imImageGetAttribute(const imImage* image, const char* attrib, int *data_type, int *count)
+{
+ assert(image);
+ assert(attrib);
+ imAttribTable* attrib_table = (imAttribTable*)image->attrib_table;
+ return attrib_table->Get(attrib, data_type, count);
+}
+
+static void iAttributeTableCopy(const void* src_attrib_table, void* dst_attrib_table)
+{
+ const imAttribTable* src_table = (const imAttribTable*)src_attrib_table;
+ imAttribTable* dst_table = (imAttribTable*)dst_attrib_table;
+ dst_table->CopyFrom(*src_table);
+}
+
+void imImageCopyAttributes(const imImage* src_image, imImage* dst_image)
+{
+ assert(src_image);
+ assert(dst_image);
+
+ if (src_image->palette && dst_image->palette &&
+ src_image->color_space == dst_image->color_space)
+ {
+ memcpy(dst_image->palette, src_image->palette, 256*sizeof(long));
+ dst_image->palette_count = src_image->palette_count;
+ }
+
+ iAttributeTableCopy(src_image->attrib_table, dst_image->attrib_table);
+}
+
+static int iAttribCB(void* user_data, int index, const char* name, int data_type, int count, const void* data)
+{
+ (void)data_type;
+ (void)data;
+ (void)count;
+ char** attrib = (char**)user_data;
+ attrib[index] = (char*)name;
+ return 1;
+}
+
+void imImageGetAttributeList(const imImage* image, char** attrib, int *attrib_count)
+{
+ assert(image);
+ assert(attrib_count);
+
+ imAttribTable* attrib_table = (imAttribTable*)image->attrib_table;
+ *attrib_count = attrib_table->Count();
+
+ if (attrib) attrib_table->ForEach((void*)attrib, iAttribCB);
+}
+
+void imImageSetPalette(imImage* image, long* palette, int palette_count)
+{
+ assert(image);
+
+ if (image->palette)
+ {
+ free(image->palette);
+ image->palette = palette;
+ image->palette_count = palette_count;
+ }
+}
+
+int imImageMatchSize(const imImage* image1, const imImage* image2)
+{
+ assert(image1);
+ assert(image2);
+
+ return ((image1->width == image2->width) &&
+ (image1->height == image2->height));
+}
+
+int imImageMatchColor(const imImage* image1, const imImage* image2)
+{
+ assert(image1);
+ assert(image2);
+
+ return (image1->data_type == image2->data_type &&
+ image1->color_space == image2->color_space);
+}
+
+int imImageMatchDataType(const imImage* image1, const imImage* image2)
+{
+ assert(image1);
+ assert(image2);
+
+ return (image1->data_type == image2->data_type &&
+ image1->width == image2->width &&
+ image1->height == image2->height);
+}
+
+int imImageMatchColorSpace(const imImage* image1, const imImage* image2)
+{
+ assert(image1);
+ assert(image2);
+
+ return (image1->width == image2->width &&
+ image1->height == image2->height &&
+ image1->color_space == image2->color_space);
+}
+
+int imImageMatch(const imImage* image1, const imImage* image2)
+{
+ assert(image1);
+ assert(image2);
+
+ return (image1->data_type == image2->data_type &&
+ image1->width == image2->width &&
+ image1->height == image2->height &&
+ image1->color_space == image2->color_space);
+}
+
+void imImageSetBinary(imImage* image)
+{
+ assert(image);
+
+ if (image->palette)
+ {
+ image->color_space = IM_BINARY;
+ image->palette_count = 2;
+ image->palette[0] = imColorEncode(0, 0, 0);
+ image->palette[1] = imColorEncode(255, 255, 255);
+ }
+}
+
+void imImageMakeBinary(imImage *image)
+{
+ assert(image);
+
+ imbyte *map = (imbyte*)image->data[0];
+ for(int i = 0; i < image->count; i++)
+ {
+ if (*map)
+ *map = 1;
+ map++;
+ }
+}
+
+void imImageMakeGray(imImage *image)
+{
+ assert(image);
+
+ imbyte *map = (imbyte*)image->data[0];
+ for(int i = 0; i < image->count; i++)
+ {
+ if (*map)
+ *map = 255;
+ map++;
+ }
+}
+
+static void iLoadImageData(imFile* ifile, imImage* image, int *error, int bitmap)
+{
+ iAttributeTableCopy(ifile->attrib_table, image->attrib_table);
+ *error = imFileReadImageData(ifile, image->data[0], bitmap, image->has_alpha);
+ if (image->color_space == IM_MAP)
+ imFileGetPalette(ifile, image->palette, &image->palette_count);
+}
+
+imImage* imFileLoadImage(imFile* ifile, int index, int *error)
+{
+ assert(ifile);
+
+ int width, height, color_mode, data_type;
+ *error = imFileReadImageInfo(ifile, index, &width, &height, &color_mode, &data_type);
+ if (*error) return NULL;
+
+ imImage* image = imImageCreate(width, height, imColorModeSpace(color_mode), data_type);
+ if (!image)
+ {
+ *error = IM_ERR_MEM;
+ return NULL;
+ }
+
+ if (imColorModeHasAlpha(color_mode))
+ imImageAddAlpha(image);
+
+ iLoadImageData(ifile, image, error, 0);
+
+ return image;
+}
+
+void imFileLoadImageFrame(imFile* ifile, int index, imImage* image, int *error)
+{
+ assert(ifile);
+
+ int width, height, color_mode, data_type;
+ *error = imFileReadImageInfo(ifile, index, &width, &height, &color_mode, &data_type);
+ if (*error) return;
+
+ // check if we can reuse the data
+ if (image->width != width ||
+ image->height != height ||
+ image->depth != imColorModeDepth(imColorModeSpace(color_mode)) ||
+ image->has_alpha != imColorModeHasAlpha(color_mode) ||
+ image->data_type != data_type)
+ {
+ *error = IM_ERR_DATA;
+ return;
+ }
+
+ image->color_space = imColorModeSpace(color_mode);
+ iLoadImageData(ifile, image, error, 0);
+}
+
+imImage* imFileLoadBitmap(imFile* ifile, int index, int *error)
+{
+ assert(ifile);
+
+ int width, height, color_mode, data_type;
+ *error = imFileReadImageInfo(ifile, index, &width, &height, &color_mode, &data_type);
+ if (*error) return NULL;
+
+ imImage* image = imImageCreate(width, height, imColorModeToBitmap(color_mode), IM_BYTE);
+ if (!image)
+ {
+ *error = IM_ERR_MEM;
+ return NULL;
+ }
+
+ if (imColorModeHasAlpha(color_mode))
+ imImageAddAlpha(image);
+
+ iLoadImageData(ifile, image, error, 1);
+
+ return image;
+}
+
+void imFileLoadBitmapFrame(imFile* ifile, int index, imImage* image, int *error)
+{
+ assert(ifile);
+
+ int width, height, color_mode, data_type;
+ *error = imFileReadImageInfo(ifile, index, &width, &height, &color_mode, &data_type);
+ if (*error) return;
+
+ // check if we can reuse the data
+ if (image->width != width ||
+ image->height != height ||
+ image->depth != imColorModeDepth(imColorModeToBitmap(color_mode)) ||
+ image->has_alpha != imColorModeHasAlpha(color_mode) ||
+ image->data_type != IM_BYTE)
+ {
+ *error = IM_ERR_DATA;
+ return;
+ }
+
+ image->color_space = imColorModeToBitmap(color_mode);
+ iLoadImageData(ifile, image, error, 1);
+}
+
+imImage* imFileLoadImageRegion(imFile* ifile, int index, int bitmap, int *error,
+ int xmin, int xmax, int ymin, int ymax, int width, int height)
+{
+ assert(ifile);
+
+ int color_mode, data_type;
+ *error = imFileReadImageInfo(ifile, index, NULL, NULL, &color_mode, &data_type);
+ if (*error) return NULL;
+
+ imImage* image = imImageCreate(width, height,
+ bitmap? imColorModeToBitmap(color_mode): imColorModeSpace(color_mode),
+ bitmap? IM_BYTE: data_type);
+ if (!image)
+ {
+ *error = IM_ERR_MEM;
+ return NULL;
+ }
+
+ if (imColorModeHasAlpha(color_mode))
+ imImageAddAlpha(image);
+
+ imFileSetAttribute(ifile, "ViewXmin", IM_INT, 1, &xmin);
+ imFileSetAttribute(ifile, "ViewXmax", IM_INT, 1, &xmax);
+ imFileSetAttribute(ifile, "ViewYmin", IM_INT, 1, &ymin);
+ imFileSetAttribute(ifile, "ViewYmax", IM_INT, 1, &ymax);
+ imFileSetAttribute(ifile, "ViewWidth", IM_INT, 1, &width);
+ imFileSetAttribute(ifile, "ViewHeight", IM_INT, 1, &height);
+
+ iLoadImageData(ifile, image, error, bitmap);
+
+ return image;
+}
+
+int imFileSaveImage(imFile* ifile, const imImage* image)
+{
+ assert(ifile);
+ assert(image);
+
+ if (image->color_space == IM_MAP)
+ imFileSetPalette(ifile, image->palette, image->palette_count);
+
+ iAttributeTableCopy(image->attrib_table, ifile->attrib_table);
+
+ int color_mode = image->color_space;
+ if (image->has_alpha)
+ color_mode |= IM_ALPHA;
+
+ int error = imFileWriteImageInfo(ifile, image->width, image->height, color_mode, image->data_type);
+ if (error) return error;
+
+ return imFileWriteImageData(ifile, image->data[0]);
+}
+
+imImage* imFileImageLoad(const char* file_name, int index, int *error)
+{
+ imFile* ifile = imFileOpen(file_name, error);
+ if (!ifile) return NULL;
+ imImage* image = imFileLoadImage(ifile, index, error);
+ imFileClose(ifile);
+ return image;
+}
+
+imImage* imFileImageLoadBitmap(const char* file_name, int index, int *error)
+{
+ imFile* ifile = imFileOpen(file_name, error);
+ if (!ifile) return NULL;
+ imImage* image = imFileLoadBitmap(ifile, index, error);
+ imFileClose(ifile);
+ return image;
+}
+
+imImage* imFileImageLoadRegion(const char* file_name, int index, int bitmap, int *error,
+ int xmin, int xmax, int ymin, int ymax, int width, int height)
+{
+ imFile* ifile = imFileOpen(file_name, error);
+ if (!ifile) return NULL;
+ imImage* image = imFileLoadImageRegion(ifile, index, bitmap, error, xmin, xmax, ymin, ymax, width, height);
+ imFileClose(ifile);
+ return image;
+}
+
+int imFileImageSave(const char* file_name, const char* format, const imImage* image)
+{
+ int error;
+ imFile* ifile = imFileNew(file_name, format, &error);
+ if (!ifile) return error;
+ error = imFileSaveImage(ifile, image);
+ imFileClose(ifile);
+ return error;
+}
diff --git a/im/src/im_lib.cpp b/im/src/im_lib.cpp
new file mode 100755
index 0000000..05a71d8
--- /dev/null
+++ b/im/src/im_lib.cpp
@@ -0,0 +1,38 @@
+/** \file
+ * \brief Library Management
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_lib.cpp,v 1.5 2009/10/01 14:43:42 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "im_lib.h"
+
+/* This appears only here to avoid changing the im_lib.h header for bug fixes */
+#define IM_VERSION_FIX ""
+#define IM_VERSION_FIX_NUMBER 0
+
+static char *iVersion = "TECVERID.str:IM:LIB:" IM_VERSION IM_VERSION_FIX;
+
+const char iIdent[] =
+ "$IM: " IM_VERSION IM_VERSION_FIX " " IM_COPYRIGHT " $\n"
+ "$URL: www.tecgraf.puc-rio.br/im $\n";
+
+const char* imVersion(void)
+{
+ (void)iVersion;
+ (void)iIdent;
+ return IM_VERSION IM_VERSION_FIX;
+}
+
+const char* imVersionDate(void)
+{
+ return IM_VERSION_DATE;
+}
+
+int imVersionNumber(void)
+{
+ return IM_VERSION_NUMBER+IM_VERSION_FIX_NUMBER;
+}
diff --git a/im/src/im_lua3.c b/im/src/im_lua3.c
new file mode 100755
index 0000000..1c85e59
--- /dev/null
+++ b/im/src/im_lua3.c
@@ -0,0 +1,1297 @@
+/** \file
+ * \brief LuaBinding for Lua 3
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_lua3.c,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lua.h>
+
+#include "im.h"
+#include "im_lib.h"
+
+#include <cd.h>
+#include <cdlua3_private.h>
+
+#include "imlua.h"
+
+
+/***************************************************************************\
+* Globals. *
+\***************************************************************************/
+static int color_tag;
+static int imagergb_tag;
+static int imagergba_tag;
+static int palette_tag;
+static int imagemap_tag;
+static int channel_tag;
+
+static channel_t channel_info;
+
+#define IMLUA_VERSION "IMLua 1.2"
+/***************************************************************************\
+* Creation and destruction functions. *
+\***************************************************************************/
+
+/***************************************************************************\
+* Creates a buffer for a RGB image. *
+\***************************************************************************/
+static void imlua_createimagergb(void)
+{
+ lua_Object width, height;
+ long int width_i, height_i;
+ imagergb_t *imagergb_p;
+
+ width = lua_getparam(1);
+ height = lua_getparam(2);
+ if (!(lua_isnumber(width) && lua_isnumber(height)))
+ lua_error("imCreateImageRGB: invalid dimensions parameter!");
+ width_i = (long int) lua_getnumber(width);
+ height_i = (long int) lua_getnumber(height);
+ if (width_i < 1 || height_i < 1)
+ lua_error("imCreateImageRGB: image dimensions should be positive integers!");
+
+ if (lua_getparam(3) != LUA_NOOBJECT)
+ lua_error("imCreateImageRGB: too many parameters!");
+
+ imagergb_p = (imagergb_t *) malloc(sizeof(imagergb_t));
+ if (!imagergb_p) {
+ lua_pushnil();
+ return;
+ }
+
+ imagergb_p->width = width_i;
+ imagergb_p->height = height_i;
+ imagergb_p->size = width_i*height_i;
+ imagergb_p->red = (unsigned char *) malloc(imagergb_p->size);
+ imagergb_p->green = (unsigned char *) malloc(imagergb_p->size);
+ imagergb_p->blue = (unsigned char *) malloc(imagergb_p->size);
+
+ if (!(imagergb_p->red && imagergb_p->green && imagergb_p->blue)) {
+ if (imagergb_p->red) free(imagergb_p->red);
+ if (imagergb_p->green) free(imagergb_p->green);
+ if (imagergb_p->blue) free(imagergb_p->blue);
+ free(imagergb_p);
+ lua_pushnil();
+ return;
+ }
+
+ memset(imagergb_p->red, 255, imagergb_p->size);
+ memset(imagergb_p->green, 255, imagergb_p->size);
+ memset(imagergb_p->blue, 255, imagergb_p->size);
+
+ lua_pushusertag((void *) imagergb_p, imagergb_tag);
+}
+
+/***************************************************************************\
+* Frees a previously allocated imagergb. We don't free imagergb_p to avoid *
+* problems if the user called killimagergb twice with the same object. The *
+* structure will be freed by a userdata "gc" fallback in LUA 3.0. *
+\***************************************************************************/
+static void imlua_killimagergb(void)
+{
+ lua_Object imagergb;
+ imagergb_t *imagergb_p;
+
+ imagergb = lua_getparam(1);
+ if (imagergb == LUA_NOOBJECT)
+ lua_error("imKillImageRGB: imagergb parameter missing!");
+ if (lua_isnil(imagergb))
+ lua_error("imKillImageRGB: attempt to kill a NIL imagergb!");
+ if (lua_tag(imagergb) != imagergb_tag)
+ lua_error("imKillImageRGB: invalid imagergb parameter!");
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+ if (!(imagergb_p->red && imagergb_p->green && imagergb_p->blue))
+ lua_error("imKillImageRGB: attempt to kill a killed imagergb!");
+
+ if (lua_getparam(2) != LUA_NOOBJECT)
+ lua_error("imKillImageRGB: too many parameters!");
+
+ free(imagergb_p->red);
+ free(imagergb_p->green);
+ free(imagergb_p->blue);
+ imagergb_p->red = NULL;
+ imagergb_p->green = NULL;
+ imagergb_p->blue = NULL;
+}
+
+/***************************************************************************\
+* Creates a palette as a palette_tag usertag lua_Object. A palette can be *
+* considered and treated as a color table. *
+\***************************************************************************/
+static void imlua_createpalette(void)
+{
+ lua_Object size;
+ long int size_i;
+ palette_t *palette_p;
+
+ size = lua_getparam(1);
+ if (!(lua_isnumber(size)))
+ lua_error("imCreatePalette: invalid palette parameter!");
+ size_i = (long int) lua_getnumber(size);
+ if (size_i < 1)
+ lua_error("imCreatePalette: palette size should be a positive integer!");
+
+ if (lua_getparam(2) != LUA_NOOBJECT)
+ lua_error("imCreatePalette: too many parameters!");
+
+ palette_p = (palette_t *) malloc(sizeof(palette_t));
+ if (!palette_p) {
+ lua_pushnil();
+ return;
+ }
+
+ palette_p->size = size_i;
+ palette_p->color = (long int *) malloc(palette_p->size * sizeof(long int));
+ if (!palette_p->color) {
+ free(palette_p);
+ lua_pushnil();
+ return;
+ }
+
+ memset(palette_p->color, 255, palette_p->size * sizeof(long int));
+ lua_pushusertag((void *) palette_p, palette_tag);
+}
+
+/***************************************************************************\
+* Frees a previously allocated palette. We don't free palette_p to prevent *
+* a problem if the user called killpalette twice with the same object. The *
+* structure will be freed by a userdata "gc" fallback in LUA 3.0. *
+\***************************************************************************/
+static void imlua_killpalette(void)
+{
+ lua_Object palette;
+ palette_t *palette_p;
+
+ palette = lua_getparam(1);
+ if (palette == LUA_NOOBJECT)
+ lua_error("imKillPalette: palette parameter missing!");
+ if (lua_isnil(palette))
+ lua_error("imKillPalette: attempt to kill a NIL palette!");
+ if (lua_tag(palette) != palette_tag)
+ lua_error("imKillPalette: invalid palette parameter!");
+ palette_p = (palette_t *) lua_getuserdata(palette);
+ if (!palette_p->color)
+ lua_error("imKillPalette: attempt to kill a killed palette!");
+
+ if (lua_getparam(2) != LUA_NOOBJECT)
+ lua_error("imKillPalette: too many parameters!");
+
+ free(palette_p->color);
+ palette_p->color = NULL;
+}
+
+/***************************************************************************\
+* Creates a imagemap as a imagemap_tag usertag lua_Object. *
+\***************************************************************************/
+static void imlua_createimagemap(void)
+{
+ lua_Object width;
+ lua_Object height;
+
+ long int width_i;
+ long int height_i;
+ imagemap_t *imagemap_p;
+
+ width = lua_getparam(1);
+ height = lua_getparam(2);
+ if (!(lua_isnumber(width) && lua_isnumber(height)))
+ lua_error("imCreateImageMap: invalid dimensions parameter!");
+ width_i = (long int) lua_getnumber(width);
+ height_i = (long int) lua_getnumber(height);
+ if (width_i < 1 || height_i < 1)
+ lua_error("imCreateImageMap: imagemap dimensions should be positive integers!");
+
+ if (lua_getparam(3) != LUA_NOOBJECT)
+ lua_error("imCreateImageMap: too many parameters!");
+
+ imagemap_p = (imagemap_t *) malloc(sizeof(imagemap_t));
+ if (!imagemap_p) {
+ lua_pushnil();
+ return;
+ }
+
+ imagemap_p->size = width_i*height_i;
+ imagemap_p->width = width_i;
+ imagemap_p->height = height_i;
+ imagemap_p->index = (unsigned char *) malloc(imagemap_p->size);
+ if (!imagemap_p->index) {
+ free(imagemap_p);
+ lua_pushnil();
+ return;
+ }
+
+ memset(imagemap_p->index, 0, imagemap_p->size);
+ lua_pushusertag((void *) imagemap_p, imagemap_tag);
+}
+
+/***************************************************************************\
+* Frees a previously allocated imagemap. We don't free imagemap_p to avoid *
+* problems if the user called killimagemap twice with the same object. The *
+* structure will be freed by a userdata "gc" fallback in LUA 3.0. *
+\***************************************************************************/
+static void imlua_killimagemap(void)
+{
+ lua_Object imagemap;
+ imagemap_t *imagemap_p;
+
+ imagemap = lua_getparam(1);
+ if (imagemap == LUA_NOOBJECT)
+ lua_error("imKillImageMap: imagemap parameter missing!");
+ if (lua_isnil(imagemap))
+ lua_error("imKillImageMap: attempt to kill a NIL imagemap!");
+ if (lua_tag(imagemap) != imagemap_tag)
+ lua_error("imKillImageMap: invalid imagemap parameter!");
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+ if (!imagemap_p->index)
+ lua_error("imKillImageMap: attempt to kill a killed imagemap!");
+
+ if (lua_getparam(2) != LUA_NOOBJECT)
+ lua_error("imKillImageMap: too many parameters!");
+
+ free(imagemap_p->index);
+ imagemap_p->index = NULL;
+}
+
+/***************************************************************************\
+* IM API Functions. *
+\***************************************************************************/
+
+/***************************************************************************\
+* imFileFormat *
+\***************************************************************************/
+static void imlua_fileformat(void)
+{
+ lua_Object file;
+
+ char *file_s;
+ int format_i;
+ int compress_i;
+
+ int err;
+
+ file = lua_getparam(1);
+ if (!lua_isstring(file))
+ lua_error("imFileFormat: invalid filename parameter!");
+ file_s = (char *) lua_getstring(file);
+
+ if (lua_getparam(2) != LUA_NOOBJECT)
+ lua_error("imFileFormat: too many parameters!");
+
+ err = imFileFormat(file_s, &format_i);
+
+ compress_i = (format_i & IM_DEFAULT) ? 1 : 0;
+ format_i = format_i & 0xFF;
+
+ /* if success, return the format */
+ if (err == IM_ERR_NONE) {
+ lua_pushnumber( format_i);
+ lua_pushnumber( compress_i);
+ }
+ /* if failure, return nil */
+ else {
+ lua_pushnil();
+ lua_pushnil();
+ }
+
+ lua_pushnumber( err);
+}
+
+/***************************************************************************\
+* imFileFormat *
+\***************************************************************************/
+static void imlua_imageinfo(void)
+{
+ lua_Object file;
+
+ char *file_s;
+
+ int width, height, image_type, pal_size;
+ int err;
+
+ file = lua_getparam(1);
+ if (!lua_isstring(file))
+ lua_error("imFileFormat: invalid filename parameter!");
+ file_s = (char *) lua_getstring(file);
+
+ if (lua_getparam(2) != LUA_NOOBJECT)
+ lua_error("imFileFormat: too many parameters!");
+
+ err = imImageInfo(file_s, &width, &height, &image_type, &pal_size);
+
+ /* if success, return the format */
+ if (err == IM_ERR_NONE) {
+ lua_pushnumber( width);
+ lua_pushnumber( height);
+ lua_pushnumber( image_type);
+ lua_pushnumber( pal_size);
+ }
+ /* if failure, return nil */
+ else {
+ lua_pushnil();
+ lua_pushnil();
+ lua_pushnil();
+ lua_pushnil();
+ }
+
+ lua_pushnumber( err);
+}
+
+/***************************************************************************\
+* imEncodeColor *
+\***************************************************************************/
+static void imlua_encodecolor(void)
+{
+ lua_Object red, green, blue;
+ float red_f, green_f, blue_f;
+ unsigned char red_i, green_i, blue_i;
+ long int color_i;
+
+ red = lua_getparam(1);
+ green = lua_getparam(2);
+ blue = lua_getparam(3);
+
+ if (lua_getparam(4) != LUA_NOOBJECT)
+ lua_error("imEncodeColor: too many parameters!");
+
+ if (!(lua_isnumber(red) && lua_isnumber(green) && lua_isnumber(blue)))
+ lua_error("imEncodeColor: invalid color component parameter!");
+
+ red_f = (float)lua_getnumber(red);
+ green_f = (float)lua_getnumber(green);
+ blue_f = (float)lua_getnumber(blue);
+
+ if (red_f < 0 || red_f > 255 || green_f < 0 ||
+ green_f > 255 || blue_f < 0 || blue_f > 255)
+ lua_error("imEncodeColor: color components values should be in range [0, 255]!");
+
+ red_i = (unsigned char) (red_f);
+ green_i = (unsigned char) (green_f);
+ blue_i = (unsigned char) (blue_f);
+
+ color_i = imEncodeColor(red_i, green_i, blue_i);
+ lua_pushusertag((void *) color_i, color_tag);
+}
+
+/***************************************************************************\
+* imDecodeColor *
+\***************************************************************************/
+static void imlua_decodecolor(void)
+{
+ lua_Object color;
+ long int color_i;
+ unsigned char red_i, green_i, blue_i;
+
+ color = lua_getparam(1);
+ if (lua_tag(color) != color_tag)
+ lua_error("imDecodeColor: invalid color parameter!");
+ color_i = (long int) lua_getuserdata(color);
+
+ if (lua_getparam(2) != LUA_NOOBJECT)
+ lua_error("imDecodeColor: too many parameters!");
+
+ imDecodeColor(&red_i, &green_i, &blue_i, color_i);
+
+ lua_pushnumber( red_i);
+ lua_pushnumber( green_i);
+ lua_pushnumber( blue_i);
+}
+
+/***************************************************************************\
+* imLoadRGB *
+\***************************************************************************/
+static void imlua_loadrgb(void)
+{
+ lua_Object file, imagergb;
+
+ imagergb_t *imagergb_p;
+ char *file_s;
+
+ int err;
+
+ file = lua_getparam(1);
+ if (!lua_isstring(file))
+ lua_error("imLoadRGB: invalid filename parameter!");
+ file_s = (char *) lua_getstring(file);
+
+ imagergb = lua_getparam(2);
+ if (lua_tag(imagergb) != imagergb_tag)
+ lua_error("imLoadRGB: invalid imagergb parameter!");
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+
+ if (lua_getparam(3) != LUA_NOOBJECT)
+ lua_error("imLoadRGB: too many parameters!");
+
+ err = imLoadRGB(file_s, imagergb_p->red, imagergb_p->green, imagergb_p->blue);
+ lua_pushnumber( err);
+}
+
+/***************************************************************************\
+* imLoadMap *
+\***************************************************************************/
+static void imlua_loadmap(void)
+{
+ lua_Object file, imagemap, palette;
+
+ imagemap_t *imagemap_p;
+ palette_t *palette_p;
+ char *file_s;
+
+ int err;
+
+ file = lua_getparam(1);
+ if (!lua_isstring(file))
+ lua_error("imLoadMap: invalid filename parameter!");
+ file_s = (char *) lua_getstring(file);
+
+ imagemap = lua_getparam(2);
+ if (lua_tag(imagemap) != imagemap_tag)
+ lua_error("imLoadMap: invalid imagemap parameter!");
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+
+ palette = lua_getparam(3);
+ if (lua_tag(palette) != palette_tag)
+ lua_error("imLoadMap: invalid palette parameter!");
+ palette_p = (palette_t *) lua_getuserdata(palette);
+
+ if (lua_getparam(4) != LUA_NOOBJECT)
+ lua_error("imLoadMap: too many parameters!");
+
+ err = imLoadMap(file_s, imagemap_p->index, palette_p->color);
+ lua_pushnumber( err);
+}
+
+/***************************************************************************\
+* imSaveRGB *
+\***************************************************************************/
+static void imlua_savergb(void)
+{
+ lua_Object file, imagergb, format, compress;
+
+ imagergb_t *imagergb_p;
+ char *file_s;
+ int format_i;
+ int compress_i;
+
+ int err;
+
+ imagergb = lua_getparam(1);
+ if (lua_tag(imagergb) != imagergb_tag)
+ lua_error("imSaveRGB: invalid imagergb parameter!");
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+
+ format = lua_getparam(2);
+ if (!lua_isnumber(format))
+ lua_error("imSaveRGB: invalid format parameter!");
+ format_i = (int) lua_getnumber(format);
+
+ compress = lua_getparam(3);
+ if (!lua_isnumber(compress))
+ lua_error("imSaveRGB: invalid compression parameter!");
+ compress_i = (int) lua_getnumber(compress);
+
+ file = lua_getparam(4);
+ if (!lua_isstring(file))
+ lua_error("imSaveRGB: invalid filename parameter!");
+ file_s = (char *) lua_getstring(file);
+
+ if (lua_getparam(5) != LUA_NOOBJECT)
+ lua_error("imSaveRGB: too many parameters!");
+
+ err = imSaveRGB(imagergb_p->width, imagergb_p->height, format_i | (compress_i << 8),
+ imagergb_p->red, imagergb_p->green, imagergb_p->blue, file_s);
+ lua_pushnumber( err);
+}
+
+/***************************************************************************\
+* imSaveMap *
+\***************************************************************************/
+static void imlua_savemap(void)
+{
+ lua_Object file, imagemap, palette, format, compress;
+
+ imagemap_t *imagemap_p;
+ palette_t *palette_p;
+ char *file_s;
+ int format_i;
+ int compress_i;
+
+ int err;
+
+ imagemap = lua_getparam(1);
+ if (lua_tag(imagemap) != imagemap_tag)
+ lua_error("imSaveMap: invalid imagemap parameter!");
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+
+ palette = lua_getparam(2);
+ if (lua_tag(palette) != palette_tag)
+ lua_error("imLoadMap: invalid palette parameter!");
+ palette_p = (palette_t *) lua_getuserdata(palette);
+
+ format = lua_getparam(3);
+ if (!lua_isnumber(format))
+ lua_error("imSaveMap: invalid format parameter!");
+ format_i = (int) lua_getnumber(format);
+
+ compress = lua_getparam(4);
+ if (!lua_isnumber(compress))
+ lua_error("imSaveMap: invalid compression parameter!");
+ compress_i = (int) lua_getnumber(compress);
+
+ file = lua_getparam(5);
+ if (!lua_isstring(file))
+ lua_error("imSaveMap: invalid filename parameter!");
+ file_s = (char *) lua_getstring(file);
+
+ if (lua_getparam(6) != LUA_NOOBJECT)
+ lua_error("imSaveMap: too many parameters!");
+
+ err = imSaveMap(imagemap_p->width, imagemap_p->height, format_i | (compress_i << 8),
+ imagemap_p->index, palette_p->size, palette_p->color, file_s);
+ lua_pushnumber( err);
+}
+
+/***************************************************************************\
+* imRGB2Map *
+\***************************************************************************/
+static void imlua_rgb2map(void)
+{
+ lua_Object imagergb, imagemap, palette;
+
+ imagemap_t *imagemap_p;
+ palette_t *palette_p;
+ imagergb_t *imagergb_p;
+
+ imagergb = lua_getparam(1);
+ if (lua_tag(imagergb) != imagergb_tag)
+ lua_error("imRGB2Map: invalid imagergb parameter!");
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+
+ imagemap = lua_getparam(2);
+ if (lua_tag(imagemap) != imagemap_tag)
+ lua_error("imRGB2Map: invalid imagemap parameter!");
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+
+ palette = lua_getparam(3);
+ if (lua_tag(palette) != palette_tag)
+ lua_error("imRGB2Map: invalid palette parameter!");
+ palette_p = (palette_t *) lua_getuserdata(palette);
+
+ if (lua_getparam(4) != LUA_NOOBJECT)
+ lua_error("imRGB2Map: too many parameters!");
+
+ if (imagergb_p->size != imagemap_p->size)
+ lua_error("imRGB2Map: images have incompatible dimensions!");
+
+ imRGB2Map(imagergb_p->width, imagergb_p->height, imagergb_p->red,
+ imagergb_p->green, imagergb_p->blue, imagemap_p->index, palette_p->size,
+ palette_p->color);
+}
+
+/***************************************************************************\
+* imMap2RGB *
+\***************************************************************************/
+static void imlua_map2rgb(void)
+{
+ lua_Object imagergb, imagemap, palette;
+
+ imagemap_t *imagemap_p;
+ palette_t *palette_p;
+ imagergb_t *imagergb_p;
+
+ imagemap = lua_getparam(1);
+ if (lua_tag(imagemap) != imagemap_tag)
+ lua_error("imMap2RGB: invalid imagemap parameter!");
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+
+ palette = lua_getparam(2);
+ if (lua_tag(palette) != palette_tag)
+ lua_error("imMap2RGB: invalid palette parameter!");
+ palette_p = (palette_t *) lua_getuserdata(palette);
+
+ imagergb = lua_getparam(3);
+ if (lua_tag(imagergb) != imagergb_tag)
+ lua_error("imMap2RGB: invalid imagergb parameter!");
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+
+ if (lua_getparam(4) != LUA_NOOBJECT)
+ lua_error("imMap2RGB: too many parameters!");
+
+ if (imagergb_p->size != imagemap_p->size)
+ lua_error("imMap2RGB: images have incompatible dimensions!");
+
+ imMap2RGB(imagemap_p->width, imagemap_p->height, imagemap_p->index, palette_p->size,
+ palette_p->color, imagergb_p->red, imagergb_p->green, imagergb_p->blue);
+}
+
+/***************************************************************************\
+* imMap2Gray *
+\***************************************************************************/
+static void imlua_map2gray(void)
+{
+ lua_Object imagemap, palette, graymap, grays;
+
+ imagemap_t *imagemap_p;
+ palette_t *palette_p;
+ imagemap_t *graymap_p;
+ palette_t *grays_p;
+
+ imagemap = lua_getparam(1);
+ if (lua_tag(imagemap) != imagemap_tag)
+ lua_error("imMap2Gray: invalid imagemap parameter!");
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+
+ palette = lua_getparam(2);
+ if (lua_tag(palette) != palette_tag)
+ lua_error("imMap2Gray: invalid palette parameter!");
+ palette_p = (palette_t *) lua_getuserdata(palette);
+
+ graymap = lua_getparam(3);
+ if (lua_tag(graymap) != imagemap_tag)
+ lua_error("imMap2Gray: invalid graymap parameter!");
+ graymap_p = (imagemap_t *) lua_getuserdata(graymap);
+
+ grays = lua_getparam(4);
+ if (lua_tag(grays) != palette_tag)
+ lua_error("imMap2Gray: invalid grays parameter!");
+ grays_p = (palette_t *) lua_getuserdata(grays);
+
+ if (lua_getparam(5) != LUA_NOOBJECT)
+ lua_error("imMap2Gray: too many parameters!");
+
+ if (imagemap_p->size != graymap_p->size)
+ lua_error("imMap2Gray: images have incompatible dimensions!");
+
+ if (grays_p->size < 256)
+ lua_error("imMap2Gray: grays palette should be of size 256!");
+
+ imMap2Gray(imagemap_p->width, imagemap_p->height, imagemap_p->index,
+ palette_p->size, palette_p->color, graymap_p->index, grays_p->color);
+}
+
+/***************************************************************************\
+* imRGB2Gray *
+\***************************************************************************/
+static void imlua_rgb2gray(void)
+{
+ lua_Object imagergb, graymap, grays;
+
+ imagergb_t *imagergb_p;
+ imagemap_t *graymap_p;
+ palette_t *grays_p;
+
+ imagergb = lua_getparam(1);
+ if (lua_tag(imagergb) != imagergb_tag)
+ lua_error("imRGB2Gray: invalid imagergb parameter!");
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+
+ graymap = lua_getparam(2);
+ if (lua_tag(graymap) != imagemap_tag)
+ lua_error("imRGB2Gray: invalid graymap parameter!");
+ graymap_p = (imagemap_t *) lua_getuserdata(graymap);
+
+ grays = lua_getparam(3);
+ if (lua_tag(grays) != palette_tag)
+ lua_error("imRGB2Gray: invalid grays parameter!");
+ grays_p = (palette_t *) lua_getuserdata(grays);
+
+ if (lua_getparam(4) != LUA_NOOBJECT)
+ lua_error("imRGB2Gray: too many parameters!");
+
+ if (imagergb_p->size != graymap_p->size)
+ lua_error("imRGB2Gray: images have incompatible dimensions!");
+
+ if (grays_p->size < 256)
+ lua_error("imRGB2Gray: grays palette should be of size 256!");
+
+ imRGB2Gray(imagergb_p->width, imagergb_p->height, imagergb_p->red,
+ imagergb_p->green, imagergb_p->blue, graymap_p->index, grays_p->color);
+}
+
+/***************************************************************************\
+* imStretch. *
+\***************************************************************************/
+static void imlua_stretch(void)
+{
+ lua_Object src, dst;
+
+ imagemap_t *srcmap_p;
+ imagemap_t *dstmap_p;
+ imagergb_t *srcrgb_p;
+ imagergb_t *dstrgb_p;
+
+ src = lua_getparam(1);
+ dst = lua_getparam(2);
+ if (lua_getparam(3) != LUA_NOOBJECT)
+ lua_error("imStretch: too many parameters!");
+
+ if ((lua_tag(src) == imagergb_tag) && (lua_tag(dst) == imagergb_tag)) {
+ srcrgb_p = (imagergb_t *) lua_getuserdata(src);
+ dstrgb_p = (imagergb_t *) lua_getuserdata(dst);
+ imStretch(srcrgb_p->width, srcrgb_p->height, srcrgb_p->red,
+ dstrgb_p->width, dstrgb_p->height, dstrgb_p->red);
+ imStretch(srcrgb_p->width, srcrgb_p->height, srcrgb_p->green,
+ dstrgb_p->width, dstrgb_p->height, dstrgb_p->green);
+ imStretch(srcrgb_p->width, srcrgb_p->height, srcrgb_p->blue,
+ dstrgb_p->width, dstrgb_p->height, dstrgb_p->blue);
+ }
+ else if ((lua_tag(src) == imagemap_tag) && (lua_tag(dst) == imagemap_tag)) {
+ srcmap_p = (imagemap_t *) lua_getuserdata(src);
+ dstmap_p = (imagemap_t *) lua_getuserdata(dst);
+ imStretch(srcmap_p->width, srcmap_p->height, srcmap_p->index,
+ dstmap_p->width, dstmap_p->height, dstmap_p->index);
+ }
+ else {
+ lua_error("imStretch: inconsistent parameters!");
+ }
+}
+
+/***************************************************************************\
+* imResize. *
+\***************************************************************************/
+static void imlua_resize(void)
+{
+ lua_Object src, dst;
+
+ imagergb_t *srcrgb_p;
+ imagergb_t *dstrgb_p;
+
+ src = lua_getparam(1);
+ dst = lua_getparam(2);
+ if (lua_getparam(3) != LUA_NOOBJECT)
+ lua_error("imResize: too many parameters!");
+
+ if ((lua_tag(src) == imagergb_tag) && (lua_tag(dst) == imagergb_tag)) {
+ srcrgb_p = (imagergb_t *) lua_getuserdata(src);
+ dstrgb_p = (imagergb_t *) lua_getuserdata(dst);
+ imStretch(srcrgb_p->width, srcrgb_p->height, srcrgb_p->red,
+ dstrgb_p->width, dstrgb_p->height, dstrgb_p->red);
+ imStretch(srcrgb_p->width, srcrgb_p->height, srcrgb_p->green,
+ dstrgb_p->width, dstrgb_p->height, dstrgb_p->green);
+ imStretch(srcrgb_p->width, srcrgb_p->height, srcrgb_p->blue,
+ dstrgb_p->width, dstrgb_p->height, dstrgb_p->blue);
+ }
+ else {
+ lua_error("imResize: parameters must be of type imagergb_tag!");
+ }
+}
+
+/***************************************************************************\
+* imVersion. *
+\***************************************************************************/
+static void imlua_version(void)
+{
+ if (lua_getparam(1) != LUA_NOOBJECT)
+ lua_error("imVersion: too many parameters!");
+
+ lua_pushstring(imVersion());
+}
+
+/***************************************************************************\
+* Fallback implementation. *
+\***************************************************************************/
+
+/***************************************************************************\
+* imagemap "settable" fallback. *
+\***************************************************************************/
+static void imagemapsettable_fb(void)
+{
+ lua_Object imagemap, index, value;
+
+ imagemap_t *imagemap_p;
+ long int index_i;
+ long int value_i;
+
+ imagemap = lua_getparam(1);
+ index = lua_getparam(2);
+ value = lua_getparam(3);
+
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+ if (!imagemap_p) {
+ lua_error("imagemap_tag \"settable\": invalid imagemap_tag object!");
+ }
+
+ if (!lua_isnumber(index)) {
+ lua_error("imagemap_tag \"settable\": index should be a number!");
+ }
+
+ if (!lua_isnumber(value)) {
+ lua_error("imagemap_tag \"settable\": value should be a number!");
+ }
+
+ value_i = (long int) lua_getnumber(value);
+ if ((value_i < 0 || value_i > 255))
+ lua_error("imagemap_tag \"settable\": value should be in range [0, 255]!");
+
+ index_i = (long int) lua_getnumber(index);
+ if (index_i < 0 || index_i >= imagemap_p->size)
+ lua_error("imagemap_tag \"settable\": index is out of bounds!");
+
+ imagemap_p->index[index_i] = (unsigned char) value_i;
+}
+
+/***************************************************************************\
+* palette "settable" fallback. *
+\***************************************************************************/
+static void palettesettable_fb(void)
+{
+ lua_Object palette, index, color;
+
+ palette_t *palette_p;
+ long int index_i;
+ long int color_i;
+
+ palette = lua_getparam(1);
+ index = lua_getparam(2);
+ color = lua_getparam(3);
+
+ palette_p = (palette_t *) lua_getuserdata(palette);
+ if (!palette_p) {
+ lua_error("palette_tag \"settable\": invalid palette_tag object!");
+ }
+
+ if (!lua_isnumber(index)) {
+ lua_error("palette_tag \"settable\": index should be a number!");
+ }
+
+ if (lua_tag(color) != color_tag)
+ lua_error("palette_tag \"settable\": value should be of type color_tag!");
+
+ color_i = (long int) lua_getuserdata(color);
+
+ index_i = (long int) lua_getnumber(index);
+ if (index_i < 0 || index_i >= palette_p->size)
+ lua_error("palette_tag \"settable\": index is out of bounds!");
+
+ palette_p->color[index_i] = color_i;
+}
+
+/***************************************************************************\
+* channel "settable" fallback. This fallback is called when a LUA line like *
+* "imagergb.r[y*w + x] = c" is executed. The imagergb "gettable" fallback *
+* fills and returns a channel structure with info about the buffer. This *
+* structure is consulted and the value is assigned where it should. *
+\***************************************************************************/
+static void channelsettable_fb(void)
+{
+ lua_Object channel, index, value;
+
+ channel_t *channel_p;
+ long int index_i;
+ long int value_i;
+
+ channel = lua_getparam(1);
+ index = lua_getparam(2);
+ value = lua_getparam(3);
+
+ channel_p = (channel_t *) lua_getuserdata(channel);
+ if (!channel_p) {
+ lua_error("channel_tag \"settable\": invalid channel_tag object!");
+ }
+
+ if (!lua_isnumber(index)) {
+ lua_error("channel_tag \"settable\": index should be a number!");
+ }
+ index_i = (long int) lua_getnumber(index);
+ if (index_i < 0 || index_i >= channel_p->size) {
+ lua_error("channel_tag \"settable\": index is out of bounds!");
+ }
+
+ if (!lua_isnumber(value)) {
+ lua_error("channel_tag \"settable\": value should be a number!");
+ }
+ value_i = (long int) lua_getnumber(value);
+ if ((value_i < 0 || value_i > 255)) {
+ lua_error("channel_tag \"settable\": value should be in range [0, 255]!");
+ }
+
+ channel_p->value[index_i] = (unsigned char) value_i;
+}
+
+/***************************************************************************\
+* imagemap "gettable" fallback. *
+\***************************************************************************/
+static void imagemapgettable_fb(void)
+{
+ lua_Object imagemap, index;
+
+ imagemap_t *imagemap_p;
+ long int index_i;
+
+ imagemap = lua_getparam(1);
+ index = lua_getparam(2);
+
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+ if (!imagemap_p)
+ lua_error("imagemap_tag \"gettable\": invalid imagemap_tag object!");
+
+ if (!lua_isnumber(index)) {
+ lua_error("imagemap_tag \"gettable\": index should be a number!");
+ }
+
+ index_i = (long int) lua_getnumber(index);
+ if (index_i < 0 || index_i >= imagemap_p->size)
+ lua_error("imagemap_tag \"gettable\": index is out of bounds!");
+
+ lua_pushnumber( imagemap_p->index[index_i]);
+}
+
+/***************************************************************************\
+* palette "gettable" fallback. *
+\***************************************************************************/
+static void palettegettable_fb(void)
+{
+ lua_Object palette, index;
+
+ palette_t *palette_p;
+ long int index_i;
+
+ palette = lua_getparam(1);
+ index = lua_getparam(2);
+
+ palette_p = (palette_t *) lua_getuserdata(palette);
+ if (!palette_p)
+ lua_error("palette_tag \"gettable\": invalid palette_tag object!");
+
+ if (!lua_isnumber(index)) {
+ lua_error("palette_tag \"gettable\": index should be a number!");
+ }
+
+ index_i = (long int) lua_getnumber(index);
+ if (index_i < 0 || index_i >= palette_p->size)
+ lua_error("palette_tag \"gettable\": index is out of bounds!");
+
+ lua_pushusertag((void *) palette_p->color[index_i], color_tag);
+}
+
+/***************************************************************************\
+* channel "gettable" fallback. This fallback is called when a LUA line like *
+* "c = imagergb.r[y*w + x]" is executed. The imagergb "gettable" fallback *
+* fills and returns a channel structure with info about the buffer. This *
+* structure is consulted and the appropriate value is returned. *
+\***************************************************************************/
+static void channelgettable_fb(void)
+{
+ lua_Object channel, index;
+
+ channel_t *channel_p;
+ long int index_i;
+
+ channel = lua_getparam(1);
+ index = lua_getparam(2);
+
+ channel_p = (channel_t *) lua_getuserdata(channel);
+ if (!channel_p) {
+ lua_error("channel_tag \"gettable\": invalid channel_tag object!");
+ }
+
+ if (!lua_isnumber(index)) {
+ lua_error("channel_tag \"gettable\": index should be a number!");
+ }
+ index_i = (long int) lua_getnumber(index);
+ if (index_i < 0 || index_i >= channel_p->size) {
+ lua_error("channel_tag \"gettable\": index is out of bounds!");
+ }
+
+ lua_pushnumber( channel_p->value[index_i]);
+}
+
+/***************************************************************************\
+* imagergb "gettable" fallback. This fallback is called when a LUA line *
+* like "c = imagergb.r[y*w + x]" or "imagergb.r[y*w + x] = c" is executed. *
+* The channel_info global is filled and its address is returned with a *
+* channel_tag usertag lua_Object. The following "gettable" or "settable" *
+* then assigns or returns the appropriate value. *
+\***************************************************************************/
+static void imagergbgettable_fb(void)
+{
+ lua_Object imagergb, index;
+
+ char *index_s;
+ imagergb_t *imagergb_p;
+
+ imagergb = lua_getparam(1);
+ index = lua_getparam(2);
+
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+ if (!imagergb_p)
+ lua_error("imagergb_tag \"gettable\": invalid imagergb_tag object!");
+
+ if (!lua_isstring(index)) {
+ lua_error("imagergb_tag \"gettable\": index should be a channel name!");
+ }
+ index_s = (char *) lua_getstring(index);
+
+ channel_info.size = imagergb_p->size;
+
+ if (*index_s == 'r' || *index_s == 'R') {
+ channel_info.value = imagergb_p->red;
+ }
+ else if (*index_s == 'g' || *index_s == 'G') {
+ channel_info.value = imagergb_p->green;
+ }
+ else if (*index_s == 'b' || *index_s == 'B') {
+ channel_info.value = imagergb_p->blue;
+ }
+ else {
+ lua_error("imagergb_tag \"gettable\": index is an invalid channel name!");
+ }
+
+ lua_pushusertag((void *) &channel_info, channel_tag);
+}
+
+/***************************************************************************\
+* imagergba "gettable" fallback. This fallback is called when a LUA line *
+* like "c = imagergba.r[y*w + x]" or "imagergba.r[y*w + x] = c" is executed.*
+* The channel_info global is filled and its address is returned with a *
+* channel_tag usertag lua_Object. The following "gettable" or "settable" *
+* then assigns or returns the appropriate value. *
+\***************************************************************************/
+static void imagergbagettable_fb(void)
+{
+ lua_Object imagergba, index;
+
+ char *index_s;
+ imagergba_t *imagergba_p;
+
+ imagergba = lua_getparam(1);
+ index = lua_getparam(2);
+
+ imagergba_p = (imagergba_t *) lua_getuserdata(imagergba);
+ if (!imagergba_p)
+ lua_error("imagergba_tag \"gettable\": invalid imagergba_tag object!");
+
+ if (!lua_isstring(index)) {
+ lua_error("imagergba_tag \"gettable\": index should be a channel name!");
+ }
+ index_s = (char *) lua_getstring(index);
+
+ channel_info.size = imagergba_p->size;
+
+ if (*index_s == 'r' || *index_s == 'R') {
+ channel_info.value = imagergba_p->red;
+ }
+ else if (*index_s == 'g' || *index_s == 'G') {
+ channel_info.value = imagergba_p->green;
+ }
+ else if (*index_s == 'b' || *index_s == 'B') {
+ channel_info.value = imagergba_p->blue;
+ }
+ else if (*index_s == 'a' || *index_s == 'A') {
+ channel_info.value = imagergba_p->alpha;
+ }
+ else {
+ lua_error("imagergba_tag \"gettable\": index is an invalid channel name!");
+ }
+
+ lua_pushusertag((void *) &channel_info, channel_tag);
+}
+
+/***************************************************************************\
+* palette "gc" fallback. *
+\***************************************************************************/
+static void palettegc_fb(void)
+{
+ lua_Object palette;
+
+ palette_t *palette_p;
+
+ palette = lua_getparam(1);
+ palette_p = (palette_t *) lua_getuserdata(palette);
+ if (!palette_p)
+ lua_error("palette_tag \"gc\": invalid palette_tag object!");
+
+ /* if the palette has not been killed, kill it */
+ if (palette_p->color) free(palette_p->color);
+
+ /* free the palette_t structure */
+ free(palette_p);
+}
+
+/***************************************************************************\
+* imagergb "gc" fallback. *
+\***************************************************************************/
+static void imagergbgc_fb(void)
+{
+ lua_Object imagergb;
+
+ imagergb_t *imagergb_p;
+
+ imagergb = lua_getparam(1);
+ imagergb_p = (imagergb_t *) lua_getuserdata(imagergb);
+ if (!imagergb_p)
+ lua_error("imagergb_tag \"gc\": invalid imagergb_tag object!");
+
+ /* if the imagergb has not been killed, kill it */
+ if (imagergb_p->red) free(imagergb_p->red);
+ if (imagergb_p->green) free(imagergb_p->green);
+ if (imagergb_p->blue) free(imagergb_p->blue);
+
+ /* free the imagergb_t structure */
+ free(imagergb_p);
+}
+
+/***************************************************************************\
+* imagergba "gc" fallback. *
+\***************************************************************************/
+static void imagergbagc_fb(void)
+{
+ lua_Object imagergba;
+
+ imagergba_t *imagergba_p;
+
+ imagergba = lua_getparam(1);
+ imagergba_p = (imagergba_t *) lua_getuserdata(imagergba);
+ if (!imagergba_p)
+ lua_error("imagergba_tag \"gc\": invalid imagergba_tag object!");
+
+ /* if the imagergba has not been killed, kill it */
+ if (imagergba_p->red) free(imagergba_p->red);
+ if (imagergba_p->green) free(imagergba_p->green);
+ if (imagergba_p->blue) free(imagergba_p->blue);
+ if (imagergba_p->alpha) free(imagergba_p->alpha);
+
+ /* free the imagergba_t structure */
+ free(imagergba_p);
+}
+
+/***************************************************************************\
+* imagemap "gc" fallback. *
+\***************************************************************************/
+static void imagemapgc_fb(void)
+{
+ lua_Object imagemap;
+
+ imagemap_t *imagemap_p;
+
+ imagemap = lua_getparam(1);
+ imagemap_p = (imagemap_t *) lua_getuserdata(imagemap);
+ if (!imagemap_p)
+ lua_error("imagemap_tag \"gc\": invalid imagemap_tag object!");
+
+ /* if the imagemap has not been killed, kill it */
+ if (imagemap_p->index) free(imagemap_p->index);
+
+ /* free the imagemap_t structure */
+ free(imagemap_p);
+}
+
+/***************************************************************************\
+* Initialization code. *
+\***************************************************************************/
+
+/***************************************************************************\
+* Initializes IMLua. *
+\***************************************************************************/
+void imlua_open(void)
+{
+ lua_Object cdlua_tag;
+
+ /* check if CD has been initialized */
+ cdlua_tag = lua_getglobal("CDLUA_INSTALLED");
+
+ /* get CD defined tags, let CD deal with the user tag objects */
+ if ((cdlua_tag != LUA_NOOBJECT) && (!lua_isnil(cdlua_tag))) {
+ cdlua_tag = lua_getglobal("CDLUA_COLOR_TAG");
+ color_tag = (int) lua_getnumber(cdlua_tag);
+ cdlua_tag = lua_getglobal("CDLUA_IMAGERGB_TAG");
+ imagergb_tag = (int) lua_getnumber(cdlua_tag);
+ cdlua_tag = lua_getglobal("CDLUA_IMAGERGBA_TAG");
+ imagergba_tag = (int) lua_getnumber(cdlua_tag);
+ cdlua_tag = lua_getglobal("CDLUA_PALETTE_TAG");
+ palette_tag = (int) lua_getnumber(cdlua_tag);
+ cdlua_tag = lua_getglobal("CDLUA_IMAGEMAP_TAG");
+ imagemap_tag = (int) lua_getnumber(cdlua_tag);
+ cdlua_tag = lua_getglobal("CDLUA_CHANNEL_TAG");
+ channel_tag = (int) lua_getnumber(cdlua_tag);
+ }
+ /* define IM own tags and fallbacks */
+ else {
+ color_tag = lua_newtag();
+ imagergb_tag = lua_newtag();
+ imagergba_tag = lua_newtag();
+ imagemap_tag = lua_newtag();
+ palette_tag = lua_newtag();
+ channel_tag = lua_newtag();
+
+ /* associate the fallbacks */
+ lua_pushcfunction(palettesettable_fb); lua_settagmethod(palette_tag, "settable");
+ lua_pushcfunction(channelsettable_fb); lua_settagmethod(channel_tag, "settable");
+ lua_pushcfunction(imagemapsettable_fb); lua_settagmethod(imagemap_tag, "settable");
+
+ lua_pushcfunction(imagergbgettable_fb); lua_settagmethod(imagergb_tag, "gettable");
+ lua_pushcfunction(imagergbagettable_fb); lua_settagmethod(imagergba_tag, "gettable");
+ lua_pushcfunction(palettegettable_fb); lua_settagmethod(palette_tag, "gettable");
+ lua_pushcfunction(imagemapgettable_fb); lua_settagmethod(imagemap_tag, "gettable");
+ lua_pushcfunction(channelgettable_fb); lua_settagmethod(channel_tag, "gettable");
+
+ lua_pushcfunction(imagergbgc_fb); lua_settagmethod(imagergb_tag, "gc");
+ lua_pushcfunction(imagergbagc_fb); lua_settagmethod(imagergba_tag, "gc");
+ lua_pushcfunction(palettegc_fb); lua_settagmethod(palette_tag, "gc");
+ lua_pushcfunction(imagemapgc_fb); lua_settagmethod(imagemap_tag, "gc");
+ }
+
+ /* register used tags in global context for other libraries use */
+ lua_pushnumber(1.0f); lua_setglobal("IMLUA_INSTALLED");
+ lua_pushnumber( color_tag); lua_setglobal("IMLUA_COLOR_TAG");
+ lua_pushnumber( imagergb_tag); lua_setglobal("IMLUA_IMAGERGB_TAG");
+ lua_pushnumber( imagergba_tag); lua_setglobal("IMLUA_IMAGERGBA_TAG");
+ lua_pushnumber( imagemap_tag); lua_setglobal("IMLUA_IMAGEMAP_TAG");
+ lua_pushnumber( palette_tag); lua_setglobal("IMLUA_PALETTE_TAG");
+ lua_pushnumber( channel_tag); lua_setglobal("IMLUA_CHANNEL_TAG");
+
+ /* registered IM functions */
+ lua_register("imDecodeColor", imlua_decodecolor);
+ lua_register("imEncodeColor", imlua_encodecolor);
+ lua_register("imLoadRGB", imlua_loadrgb);
+ lua_register("imLoadMap", imlua_loadmap);
+ lua_register("imSaveRGB", imlua_savergb);
+ lua_register("imSaveMap", imlua_savemap);
+ lua_register("imFileFormat", imlua_fileformat);
+ lua_register("imImageInfo", imlua_imageinfo);
+ lua_register("imRGB2Map", imlua_rgb2map);
+ lua_register("imMap2RGB", imlua_map2rgb);
+ lua_register("imRGB2Gray", imlua_rgb2gray);
+ lua_register("imMap2Gray", imlua_map2gray);
+ lua_register("imVersion", imlua_version);
+ lua_register("imResize", imlua_resize);
+ lua_register("imStretch", imlua_stretch);
+
+ /* creation and destruction functions */
+ lua_register("imCreateImageRGB", imlua_createimagergb);
+ lua_register("imCreateImageMap", imlua_createimagemap);
+ lua_register("imCreatePalette", imlua_createpalette);
+ lua_register("imKillImageRGB", imlua_killimagergb);
+ lua_register("imKillImageMap", imlua_killimagemap);
+ lua_register("imKillPalette", imlua_killpalette);
+
+ /* im constants */
+ lua_pushnumber( IM_BMP); lua_setglobal("IM_BMP");
+ lua_pushnumber( IM_PCX); lua_setglobal("IM_PCX");
+ lua_pushnumber( IM_GIF); lua_setglobal("IM_GIF");
+ lua_pushnumber( IM_TIF); lua_setglobal("IM_TIF");
+ lua_pushnumber( IM_RAS); lua_setglobal("IM_RAS");
+ lua_pushnumber( IM_SGI); lua_setglobal("IM_SGI");
+ lua_pushnumber( IM_JPG); lua_setglobal("IM_JPG");
+ lua_pushnumber( IM_LED); lua_setglobal("IM_LED");
+ lua_pushnumber( IM_TGA); lua_setglobal("IM_TGA");
+
+ lua_pushnumber( 0); lua_setglobal("IM_NONE");
+ lua_pushnumber( 1); lua_setglobal("IM_DEFAULT");
+ lua_pushnumber( 2); lua_setglobal("IM_COMPRESSED");
+
+ lua_pushnumber( IM_RGB); lua_setglobal("IM_RGB");
+ lua_pushnumber( IM_MAP); lua_setglobal("IM_MAP");
+
+ lua_pushnumber( IM_ERR_NONE); lua_setglobal("IM_ERR_NONE");
+ lua_pushnumber( IM_ERR_OPEN); lua_setglobal("IM_ERR_OPEN");
+ lua_pushnumber( IM_ERR_READ); lua_setglobal("IM_ERR_READ");
+ lua_pushnumber( IM_ERR_WRITE); lua_setglobal("IM_ERR_WRITE");
+ lua_pushnumber( IM_ERR_FORMAT); lua_setglobal("IM_ERR_FORMAT");
+ lua_pushnumber( IM_ERR_TYPE); lua_setglobal("IM_ERR_TYPE");
+ lua_pushnumber( IM_ERR_COMP); lua_setglobal("IM_ERR_COMP");
+}
diff --git a/im/src/im_palette.cpp b/im/src/im_palette.cpp
new file mode 100755
index 0000000..0e6f967
--- /dev/null
+++ b/im/src/im_palette.cpp
@@ -0,0 +1,551 @@
+/** \file
+ * \brief Palette Generators
+ * Creates several standard palettes
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_palette.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_util.h"
+#include "im_palette.h"
+#include "im_colorhsi.h"
+
+#include <stdlib.h>
+#include <memory.h>
+#include <assert.h>
+#include <math.h>
+
+static inline int iSqr(int x)
+{
+ return x*x;
+}
+
+static inline int iAbs(int x)
+{
+ return x < 0? -x: x;
+}
+
+int imPaletteFindNearest(const long* palette, int palette_count, long color)
+{
+ assert(palette);
+ assert(palette_count);
+
+ int lSqrDiff, lBestDiff = (unsigned int)-1;
+ int pIndex = -1;
+
+ imbyte red1, green1, blue1;
+ imColorDecode(&red1, &green1, &blue1, color);
+
+ for (int lIndex = 0; lIndex < palette_count; lIndex++, palette++)
+ {
+ if (color == *palette)
+ return lIndex;
+
+ imbyte red2, green2, blue2;
+ imColorDecode(&red2, &green2, &blue2, *palette);
+
+ lSqrDiff = iSqr(red1 - red2) +
+ iSqr(green1 - green2) +
+ iSqr(blue1 - blue2);
+
+ if (lSqrDiff < lBestDiff)
+ {
+ lBestDiff = lSqrDiff;
+ pIndex = lIndex;
+ }
+ }
+
+ return pIndex;
+}
+
+int imPaletteFindColor(const long* palette, int palette_count, long color, unsigned char tol)
+{
+ assert(palette);
+ assert(palette_count);
+
+ /* Divides in two section for faster results when Tolerance is 0.*/
+ if (tol == 0)
+ {
+ for (int lIndex = 0; lIndex < palette_count; lIndex++, palette++)
+ {
+ if (color == *palette)
+ return lIndex;
+ }
+ }
+ else
+ {
+ imbyte red1, green1, blue1;
+ imColorDecode(&red1, &green1, &blue1, color);
+
+ for (int lIndex = 0; lIndex < palette_count; lIndex++, palette++)
+ {
+ imbyte red2, green2, blue2;
+ imColorDecode(&red2, &green2, &blue2, *palette);
+
+ if (iAbs(red1 - red2) < tol &&
+ iAbs(green1 - green2) < tol &&
+ iAbs(blue1 - blue2) < tol)
+ {
+ return lIndex;
+ }
+ }
+ }
+
+ return -1;
+}
+
+long* imPaletteGray(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 0) to (255, 255, 255)*/
+ /* From Black to White */
+ *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, (imbyte)lIndex);
+ }
+
+ return palette;
+}
+
+long* imPaletteRed(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 0) to (255, 0, 0) */
+ /* From Black to Red */
+ *(ct++) = imColorEncode((imbyte)lIndex, 0, 0);
+ }
+
+ return palette;
+}
+
+long* imPaletteGreen(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 0) to (0, 255, 0)*/
+ /* From Black to Green */
+ *(ct++) = imColorEncode(0, (imbyte)lIndex, 0);
+ }
+
+ return palette;
+}
+
+long* imPaletteBlue(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 0) to (0, 0, 255)*/
+ /* From Black to Blue */
+ *(ct++) = imColorEncode(0, 0, (imbyte)lIndex);
+ }
+
+ return palette;
+}
+
+long* imPaletteYellow(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 0) to (255, 255, 0)*/
+ /* From Black to Yellow */
+ *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, 0);
+ }
+
+ return palette;
+}
+
+long* imPaletteMagenta(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 0) to (255, 0, 255)*/
+ /* From Black to Magenta */
+ *(ct++) = imColorEncode((imbyte)lIndex, 0, (imbyte)lIndex);
+ }
+
+ return palette;
+}
+
+long* imPaletteCian(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 0) to (0, 255, 255)*/
+ /* From Black to Cian */
+ *(ct++) = imColorEncode(0, (imbyte)lIndex, (imbyte)lIndex);
+ }
+
+ return palette;
+}
+
+long* imPaletteHues(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+ int i;
+ float tone, step1 = 255.0f/41.0f, step2 = 255.0f/42.0f;
+
+ /* 1+42+1+41+1+42+1+41+1+42+1+41+1 = 256 */
+
+ /* red */
+ *(ct++) = imColorEncode((imbyte)255, 0, 0);
+
+ for (tone = step2, i = 0; i < 42; i++, tone += step2)
+ {
+ /* From (255, 0, 0) to (255, 255, 0) */
+ /* From Red to Yellow */
+ *(ct++) = imColorEncode((imbyte)255, (imbyte)tone, 0);
+ }
+
+ /* yellow */
+ *(ct++) = imColorEncode((imbyte)255, (imbyte)255, 0);
+
+ for (tone = step1, i = 0; i < 41; i++, tone += step1)
+ {
+ /* From (255, 255, 0) to (0, 255, 0) */
+ /* From Yellow to Green */
+ *(ct++) = imColorEncode((imbyte)(255.0f-tone), (imbyte)255, 0);
+ }
+
+ /* green */
+ *(ct++) = imColorEncode(0, (imbyte)255, 0);;
+
+ for (tone = step2, i = 0; i < 42; i++, tone += step2)
+ {
+ /* From (0, 255, 0) to (0, 255, 255) */
+ /* From Green to Cian */
+ *(ct++) = imColorEncode(0, (imbyte)255, (imbyte)tone);
+ }
+
+ /* cian */
+ *(ct++) = imColorEncode(0, (imbyte)255, (imbyte)255);
+
+ for (tone = step1, i = 0; i < 41; i++, tone += step1)
+ {
+ /* From (0, 255, 255) to (0, 0, 255) */
+ /* From Cian to Blue */
+ *(ct++) = imColorEncode(0, (imbyte)(255.0f-tone), (imbyte)255);
+ }
+
+ /* blue */
+ *(ct++) = imColorEncode(0, 0, (imbyte)255);
+
+ for (tone = step2, i = 0; i < 42; i++, tone += step2)
+ {
+ /* From (0, 0, 255) to (255, 0, 255) */
+ /* From Blue to Magenta */
+ *(ct++) = imColorEncode((imbyte)tone, 0, (imbyte)255);
+ }
+
+ /* magenta */
+ *(ct++) = imColorEncode((imbyte)255, 0, (imbyte)255);
+
+ for (tone = step1, i = 0; i < 41; i++, tone += step1)
+ {
+ /* From (255, 0, 255) to (255, 0, 0) */
+ /* From Magenta to Red */
+ *(ct++) = imColorEncode((imbyte)255, 0, (imbyte)(255.0f-tone));
+ }
+
+ /* black */
+ *(ct++) = imColorEncode(0, 0, 0);;
+
+ return palette;
+}
+
+long* imPaletteRainbow(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+ int hue;
+ unsigned char r, g, b;
+ float h, s, i, factor, H;
+
+ s = 1.0f;
+ factor = 360.0f / 256.0f;
+
+ for (hue = 0; hue < 256; hue++)
+ {
+ h = hue * factor;
+ h = 300-h;
+ if (h < 0) h += 360;
+ H = h/57.2957795131f;
+
+ i = imColorHSI_ImaxS(H, cos(H), sin(H));
+
+ imColorHSI2RGBbyte(h, s, i, &r, &g, &b);
+
+ *(ct++) = imColorEncode(r, g, b);;
+ }
+
+ return palette;
+}
+
+long* imPaletteBlueIce(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lIndex = 0; lIndex < 256; lIndex++)
+ {
+ /* From (0, 0, 255) to (255, 255, 255)*/
+ /* From Blue to White */
+ *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, 255);
+ }
+
+ return palette;
+}
+
+long* imPaletteHotIron(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+ int lIndex, lSubIndex;
+
+ for (lIndex = 0, lSubIndex = 0; lSubIndex < 128; lSubIndex++, lIndex += 2)
+ {
+ /* From (0, 0, 0) to (254, 0, 0) */
+ /* From Black to ~Red */
+ *(ct++) = imColorEncode((imbyte)lIndex, 0, 0);
+ }
+
+ for (lIndex = 0, lSubIndex = 0; lSubIndex < 64; lSubIndex++, lIndex += 2)
+ {
+ /* From (255, 0, 0) to (255, 126, 0) */
+ /* From Red to ~Orange */
+ *(ct++) = imColorEncode(255, (imbyte)lIndex, 0);
+ }
+
+ for (lIndex = 0, lSubIndex = 0; lSubIndex < 63; lSubIndex++, lIndex += 2)
+ {
+ /* From (255, 128, 0) to (255, 252, 252)*/
+ /* From Orange to ~White */
+ imbyte red = 255;
+ imbyte green = (imbyte)(128 + lIndex);
+ imbyte blue = (imbyte)(lIndex * 2 + 4);
+
+ *(ct++) = imColorEncode(red, green, blue);
+ }
+
+ *(ct++) = imColorEncode(255, 255, 255);
+
+ return palette;
+}
+
+long* imPaletteBlackBody(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+ int lIndex, lSubIndex;
+
+ for (lIndex = 0, lSubIndex = 0; lSubIndex < 85; lSubIndex++, lIndex += 3)
+ {
+ /* From (0, 0, 0) to (252, 0, 0) */
+ /* From Black to ~Red */
+ *(ct++) = imColorEncode((imbyte)lIndex, 0, 0);
+ }
+
+ for (lIndex = 0, lSubIndex = 0; lSubIndex < 85; lSubIndex++, lIndex += 3)
+ {
+ /* From (255, 0, 0) to (255, 252, 0)*/
+ /* From Red to ~Yellow */
+ *(ct++) = imColorEncode(255, (imbyte)lIndex, 0);
+ }
+
+ for (lIndex = 0, lSubIndex = 0; lSubIndex < 86; lSubIndex++, lIndex += 3)
+ {
+ /* From (255, 255, 0) to (255, 255, 255)*/
+ /* From Yellow to White */
+ *(ct++) = imColorEncode(255, 255, (imbyte)lIndex);
+ }
+
+ return palette;
+}
+
+long* imPaletteHighContrast(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+ int lIndex;
+
+ static struct{unsigned char r, g, b;} HighContrastColors[65] = {
+ { 0,0,0 },
+
+ { 255,0,0 }, { 128,0,0 }, { 64,0,0 }, { 192,0,0 },
+ { 0,255,0 }, { 0,128,0 }, { 0,64,0 }, { 0,192,0 },
+ { 0,0,255 }, { 0,0,128 }, { 0,0,64 }, { 0,0,192 },
+ { 255,255,0 }, { 128,128,0 }, { 64,64,0 }, { 192,192,0 },
+ { 255,0,255 }, { 128,0,128 }, { 64,0,64 }, { 192,0,192 },
+ { 0,255,255 }, { 0,128,128 }, { 0,64,64 }, { 0,192,192 },
+ { 255,255,255 }, { 128,128,128 }, { 64,64,64 }, { 192,192,192 },
+
+ { 255,128,128 }, { 64,255,255 }, { 192,255,255 },
+ { 128,255,128 }, { 255,64,255 }, { 255,192,255 },
+ { 128,128,255 }, { 255,255,64 }, { 255,255,192 },
+ { 255,255,128 }, { 64,64,255 }, { 192,192,255 },
+ { 255,128,255 }, { 64,255,64 }, { 192,255,192 },
+ { 128,255,255 }, { 255,64,64 }, { 255,192,192 },
+
+ { 128,64,64 }, { 128,192,192 },
+ { 64,128,64 }, { 192,128,192 },
+ { 64,64,128 }, { 192,192,128 },
+ { 128,128,64 }, { 128,128,192 },
+ { 128,64,128 }, { 128,192,128 },
+ { 64,128,128 }, { 192,128,128 },
+
+ { 192,64,64 },
+ { 64,192,64 },
+ { 64,64,192 },
+ { 192,192,64 },
+ { 192,64,192 },
+ { 64,192,192 },
+ };
+
+ for (lIndex = 0; lIndex < 65; lIndex++)
+ {
+ *(ct++) = imColorEncode(HighContrastColors[lIndex].r,
+ HighContrastColors[lIndex].g,
+ HighContrastColors[lIndex].b);
+ }
+
+ for (; lIndex < 256; lIndex++)
+ {
+ *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, (imbyte)lIndex);
+ }
+
+ return palette;
+}
+
+/* 256 divided in 6 steps results in these steps.*/
+static int iSixStepsTable[6] = {0, 51, 102, 153, 204, 255};
+
+long* imPaletteUniform(void)
+{
+ long* palette = (long*)malloc(sizeof(long)*256);
+ long* ct = palette;
+
+ for (int lRedIndex = 0; lRedIndex < 6; lRedIndex++)
+ for (int lGreenIndex = 0; lGreenIndex < 6; lGreenIndex++)
+ for (int lBlueIndex = 0; lBlueIndex < 6; lBlueIndex++)
+ {
+ imbyte red = (imbyte)iSixStepsTable[lRedIndex];
+ imbyte green = (imbyte)iSixStepsTable[lGreenIndex];
+ imbyte blue = (imbyte)iSixStepsTable[lBlueIndex];
+
+ *(ct++) = imColorEncode(red, green, blue);
+ }
+
+ /* We initialize only 216 colors (6x6x6), rest 40 colors.*/
+ /* Fill them with a gray scale palette.*/
+ for (int lIndex = 6; lIndex < 246; lIndex += 6)
+ {
+ *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, (imbyte)lIndex);
+ }
+
+ return palette;
+}
+
+/* X divided by 51. Convert to 216 color space. */
+static int iDividedBy51Table[256] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5
+};
+
+/* X multiplied by 36. Shift to red position.*/
+static int iTimes36Table[6] = {0, 36, 72, 108, 144, 180};
+
+/* X multiplied by 36. Shift to green position.*/
+static int iTimes6Table[6] = {0, 6, 12, 18, 24, 30};
+
+int imPaletteUniformIndex(long color)
+{
+ imbyte red, green, blue;
+ imColorDecode(&red, &green, &blue, color);
+ return iTimes36Table[iDividedBy51Table[red]] + iTimes6Table[iDividedBy51Table[green]] + iDividedBy51Table[blue];
+}
+
+/* Remainder of X divided by 51. Used to position in the halftone*/
+static int iModulo51Table[256] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0
+};
+
+/* Dither matrices for 8 bit to 2.6 bit halftones.*/
+static int iHalftone8x8Table[64] =
+{
+ 0, 38, 9, 47, 2, 40, 11, 50,
+ 25, 12, 35, 22, 27, 15, 37, 24,
+ 6, 44, 3, 41, 8, 47, 5, 43,
+ 31, 19, 28, 15, 34, 21, 31, 18,
+ 1, 39, 11, 49, 0, 39, 10, 48,
+ 27, 14, 36, 23, 26, 13, 35, 23,
+ 7, 46, 4, 43, 7, 45, 3, 42,
+ 33, 20, 30, 17, 32, 19, 29, 16
+};
+
+int imPaletteUniformIndexHalftoned(long color, int x, int y)
+{
+ int lHalf = iHalftone8x8Table[(x % 8) * 8 + y % 8];
+
+ imbyte red, green, blue;
+ imColorDecode(&red, &green, &blue, color);
+
+ /* Now, look up each value in the halftone matrix using an 8x8 ordered dither.*/
+ int lRed = iDividedBy51Table[red] + (iModulo51Table[red] > lHalf? 1: 0);
+ int lGreen = iDividedBy51Table[green] + (iModulo51Table[green] > lHalf? 1: 0);
+ int lBlue = iDividedBy51Table[blue] + (iModulo51Table[blue] > lHalf? 1: 0);
+
+ return iTimes36Table[lRed] + iTimes6Table[lGreen] + lBlue;
+}
diff --git a/im/src/im_process.def b/im/src/im_process.def
new file mode 100755
index 0000000..07bba47
--- /dev/null
+++ b/im/src/im_process.def
@@ -0,0 +1,165 @@
+EXPORTS
+ imCalcRMSError
+ imCalcSNR
+ imProcessAutoCovariance
+ imProcessBinMorphClose
+ imProcessBinMorphConvolve
+ imProcessBinMorphDilate
+ imProcessBinMorphErode
+ imProcessBinMorphOpen
+ imProcessBinMorphOutline
+ imProcessCompassConvolve
+ imProcessConvolve
+ imProcessConvolveRep
+ imProcessConvolveSep
+ imProcessDiffOfGaussianConvolve
+ imProcessGaussianConvolve
+ imProcessGrayMorphClose
+ imProcessGrayMorphConvolve
+ imProcessGrayMorphDilate
+ imProcessGrayMorphErode
+ imProcessGrayMorphGradient
+ imProcessGrayMorphOpen
+ imProcessGrayMorphTopHat
+ imProcessGrayMorphWell
+ imProcessHoughLines
+ imProcessHoughLinesDraw
+ imProcessLapOfGaussianConvolve
+ imProcessLocalMaxThreshold
+ imProcessMeanConvolve
+ imProcessMedianConvolve
+ imProcessMinMaxThreshold
+ imProcessOtsuThreshold
+ imProcessPercentThreshold
+ imProcessRadial
+ imProcessRangeContrastThreshold
+ imProcessRangeConvolve
+ imProcessRankClosestConvolve
+ imProcessRankMaxConvolve
+ imProcessRankMinConvolve
+ imProcessReduce
+ imProcessRenderAddGaussianNoise
+ imProcessRenderAddSpeckleNoise
+ imProcessRenderAddUniformNoise
+ imProcessRenderBox
+ imProcessRenderCondOp
+ imProcessRenderCone
+ imProcessRenderConstant
+ imProcessRenderCosine
+ imProcessRenderGaussian
+ imProcessRenderLapOfGaussian
+ imProcessRenderOp
+ imProcessRenderRamp
+ imProcessRenderRandomNoise
+ imProcessRenderSinc
+ imProcessRenderTent
+ imProcessRenderWheel
+ imProcessResize
+ imProcessRotate
+ imProcessSobelConvolve
+ imProcessUniformErrThreshold
+ imCalcCountColors
+ imCalcGrayHistogram
+ imCalcHistogram
+ imCalcHistogramStatistics
+ imCalcHistoImageStatistics
+ imCalcImageStatistics
+ imProcessPixelate
+ imProcessArithmeticConstOp
+ imProcessArithmeticOp
+ imProcessBinMorphThin
+ imProcessBitMask
+ imProcessBitPlane
+ imProcessBitwiseOp
+ imProcessBlendConst
+ imProcessBlend
+ imProcessCalcRotateSize
+ imProcessDifusionErrThreshold
+ imProcessDirectConv
+ imProcessEqualizeHistogram
+ imProcessExpandHistogram
+ imProcessFlip
+ imProcessHysteresisThresEstimate
+ imProcessHysteresisThreshold
+ imProcessLocalMaxThresEstimate
+ imProcessMergeComplex
+ imProcessMergeComponents
+ imProcessMergeHSI
+ imProcessMirror
+ imProcessMultipleMean
+ imProcessMultipleStdDev
+ imProcessQuantizeGrayUniform
+ imProcessQuantizeRGBUniform
+ imProcessReduceBy4
+ imProcessRotate180
+ imProcessRotate90
+ imProcessSplitComplex
+ imProcessSplitComponents
+ imProcessSplitHSI
+ imProcessSplitYChroma
+ imProcessThreshold
+ imProcessThresholdByDiff
+ imProcessToneGamut
+ imProcessUnArithmeticOp
+ imProcessUnNormalize
+ imProcessZeroCrossing
+ imProcessRotateKernel
+ imProcessAddMargins
+ imProcessReplaceColor
+ imProcessPosterize
+ imProcessNegative
+ imProcessCanny
+ imProcessMultiplyConj
+ imProcessNormalizeComponents
+ imGaussianStdDev2KernelSize
+ imProcessBitwiseNot
+ imProcessDistanceTransform
+ imAnalyzeFindRegions
+ imAnalyzeMeasureArea
+ imAnalyzeMeasureCentroid
+ imAnalyzeMeasurePrincipalAxis
+ imAnalyzeMeasureHoles
+ imProcessPerimeterLine
+ imAnalyzeMeasurePerimeter
+ imProcessRemoveByArea
+ imProcessFillHoles
+ imAnalyzeMeasurePerimArea
+ imProcessSliceThreshold
+ imProcessRenderGrid
+ imProcessRenderChessboard
+ imProcessInsert
+ imProcessCrop
+ imProcessRegionalMaximum
+ imCalcUShortHistogram
+ imProcessSwirl
+ imProcessPrewittConvolve
+ imProcessSplineEdgeConvolve
+ imProcessConvolveDual
+ imKernelSobel
+ imKernelPrewitt
+ imKernelKirsh
+ imKernelLaplacian4
+ imKernelLaplacian8
+ imKernelLaplacian5x5
+ imKernelLaplacian7x7
+ imKernelGradian3x3
+ imKernelGradian7x7
+ imKernelSculpt
+ imKernelMean3x3
+ imKernelMean5x5
+ imKernelCircularMean5x5
+ imKernelMean7x7
+ imKernelCircularMean7x7
+ imKernelGaussian3x3
+ imKernelGaussian5x5
+ imKernelBarlett5x5
+ imKernelTopHat5x5
+ imKernelTopHat7x7
+ imKernelEnhance
+ imGaussianKernelSize2StdDev
+ imProcessRotateRef
+ imProcessInterlaceSplit
+ imProcessBarlettConvolve
+ imProcessUnsharp
+ imProcessSharp
+ imProcessSharpKernel
diff --git a/im/src/im_process.dep b/im/src/im_process.dep
new file mode 100644
index 0000000..83b76c9
--- /dev/null
+++ b/im/src/im_process.dep
@@ -0,0 +1,84 @@
+$(OBJDIR)/im_arithmetic_bin.o: process/im_arithmetic_bin.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_math.h \
+ ../include/im_util.h ../include/im_complex.h ../include/im_math.h \
+ ../include/im_counter.h ../include/im_process_pon.h \
+ ../include/im_image.h ../include/im_math_op.h ../include/im_complex.h
+$(OBJDIR)/im_morphology_gray.o: process/im_morphology_gray.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_convert.h ../include/im_image.h \
+ ../include/im_process_loc.h ../include/im_process_pon.h
+$(OBJDIR)/im_quantize.o: process/im_quantize.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_palette.h \
+ ../include/im_math.h ../include/im_util.h ../include/im_process_pon.h \
+ ../include/im_image.h
+$(OBJDIR)/im_arithmetic_un.o: process/im_arithmetic_un.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_math.h \
+ ../include/im_util.h ../include/im_complex.h ../include/im_math.h \
+ ../include/im_process_pon.h ../include/im_image.h \
+ ../include/im_math_op.h ../include/im_complex.h
+$(OBJDIR)/im_geometric.o: process/im_geometric.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_process_loc.h ../include/im_image.h \
+ ../include/im_math_op.h ../include/im_complex.h ../include/im_math.h \
+ ../include/im_util.h
+$(OBJDIR)/im_render.o: process/im_render.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_counter.h ../include/im_math.h \
+ ../include/im_util.h ../include/im_process_pon.h ../include/im_image.h
+$(OBJDIR)/im_color.o: process/im_color.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_colorhsi.h ../include/im_palette.h \
+ ../include/im_process_pon.h ../include/im_image.h
+$(OBJDIR)/im_histogram.o: process/im_histogram.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_math.h \
+ ../include/im_util.h ../include/im_process_pon.h ../include/im_image.h \
+ ../include/im_process_ana.h
+$(OBJDIR)/im_resize.o: process/im_resize.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_math.h ../include/im_util.h \
+ ../include/im_complex.h ../include/im_math.h ../include/im_counter.h \
+ ../include/im_process_loc.h ../include/im_image.h
+$(OBJDIR)/im_convolve.o: process/im_convolve.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_complex.h ../include/im_math.h ../include/im_util.h \
+ ../include/im_math_op.h ../include/im_complex.h ../include/im_image.h \
+ ../include/im_kernel.h ../include/im_process_loc.h \
+ ../include/im_image.h ../include/im_process_pon.h
+$(OBJDIR)/im_houghline.o: process/im_houghline.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_complex.h \
+ ../include/im_math.h ../include/im_util.h ../include/im_convert.h \
+ ../include/im_image.h ../include/im_counter.h \
+ ../include/im_process_glo.h
+$(OBJDIR)/im_statistics.o: process/im_statistics.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_math_op.h \
+ ../include/im_complex.h ../include/im_math.h ../include/im_util.h \
+ ../include/im_process_ana.h ../include/im_image.h
+$(OBJDIR)/im_convolve_rank.o: process/im_convolve_rank.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_math.h ../include/im_util.h ../include/im_process_loc.h \
+ ../include/im_image.h
+$(OBJDIR)/im_logic.o: process/im_logic.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_process_pon.h ../include/im_image.h
+$(OBJDIR)/im_threshold.o: process/im_threshold.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_process_pon.h \
+ ../include/im_image.h ../include/im_process_ana.h
+$(OBJDIR)/im_effects.o: process/im_effects.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_math.h ../include/im_util.h \
+ ../include/im_complex.h ../include/im_math.h \
+ ../include/im_process_pon.h ../include/im_image.h \
+ ../include/im_math_op.h ../include/im_complex.h
+$(OBJDIR)/im_morphology_bin.o: process/im_morphology_bin.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_counter.h \
+ ../include/im_process_loc.h ../include/im_image.h \
+ ../include/im_process_pon.h
+$(OBJDIR)/im_tonegamut.o: process/im_tonegamut.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_math.h \
+ ../include/im_util.h ../include/im_process_pon.h ../include/im_image.h
+$(OBJDIR)/im_canny.o: process/im_canny.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_process_loc.h ../include/im_image.h
+$(OBJDIR)/im_distance.o: process/im_distance.cpp ../include/im.h \
+ ../include/old_im.h ../include/im_util.h ../include/im_process_glo.h \
+ ../include/im_image.h
+$(OBJDIR)/im_analyze.o: process/im_analyze.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_math.h ../include/im_util.h \
+ ../include/im_process_ana.h ../include/im_image.h \
+ ../include/im_process_pon.h
+$(OBJDIR)/im_kernel.o: process/im_kernel.cpp ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_image.h ../include/im_kernel.h
diff --git a/im/src/im_process.mak b/im/src/im_process.mak
new file mode 100755
index 0000000..064be76
--- /dev/null
+++ b/im/src/im_process.mak
@@ -0,0 +1,36 @@
+PROJNAME = im
+LIBNAME = im_process
+OPT = YES
+
+SRC = \
+ im_arithmetic_bin.cpp im_morphology_gray.cpp im_quantize.cpp \
+ im_arithmetic_un.cpp im_geometric.cpp im_render.cpp \
+ im_color.cpp im_histogram.cpp im_resize.cpp \
+ im_convolve.cpp im_houghline.cpp im_statistics.cpp \
+ im_convolve_rank.cpp im_logic.cpp im_threshold.cpp \
+ im_effects.cpp im_morphology_bin.cpp im_tonegamut.cpp \
+ im_canny.cpp im_distance.cpp im_analyze.cpp \
+ im_kernel.cpp
+SRC := $(addprefix process/, $(SRC))
+
+USE_IM = Yes
+IM = ..
+
+ifneq ($(findstring Win, $(TEC_SYSNAME)), )
+ ifneq ($(findstring ow, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+ endif
+ ifneq ($(findstring bc, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+ endif
+else
+ ifneq ($(findstring AIX, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+ endif
+ ifneq ($(findstring SunOS, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+ endif
+ ifneq ($(findstring HP-UX, $(TEC_UNAME)), )
+ DEFINES += IM_DEFMATHFLOAT
+ endif
+endif
diff --git a/im/src/im_rgb2map.cpp b/im/src/im_rgb2map.cpp
new file mode 100755
index 0000000..465743a
--- /dev/null
+++ b/im/src/im_rgb2map.cpp
@@ -0,0 +1,964 @@
+/** \file
+ * \brief RGB to Map Conversion
+ *
+ * Most part of this code is based on jquant2.c from version 5
+ * of the IJG JPEG software,
+ * copyright (C) 1991-1994, Thomas G. Lane.
+ * Some other parts are from XV software
+ * copyright John Bradley.
+ * This file doen not follows the IM library nomenclature convention.
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_rgb2map.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+
+#include "im.h"
+#include "im_util.h"
+#include "im_convert.h"
+#include "im_counter.h"
+
+
+/* RANGE forces a to be in the range b..c (inclusive) */
+#define RANGE(a,b,c) { if (a < b) a = b; if (a > c) a = c; }
+
+static void xvbcopy(const imbyte* src, imbyte* dst, int len)
+{
+ /* determine if the regions overlap
+ *
+ * 3 cases: src=dst, src<dst, src>dst
+ *
+ * if src=dst, they overlap completely, but nothing needs to be moved
+ * if src<dst and src+len>dst then they overlap
+ * if src>dst and src<dst+len then they overlap
+ */
+
+ if (src==dst || len<=0) return; /* nothin' to do */
+
+ if (src<dst && src+len>dst) { /* do a backward copy */
+ src = src + len - 1;
+ dst = dst + len - 1;
+ for ( ; len>0; len--, src--, dst--) *dst = *src;
+ }
+
+ else { /* they either overlap (src>dst) or they don't overlap */
+ /* do a forward copy */
+ for ( ; len>0; len--, src++, dst++) *dst = *src;
+ }
+}
+
+/****************************/
+static int quick_map(imbyte *red, imbyte *green, imbyte *blue, int w, int h, imbyte *map,
+ imbyte *rmap, imbyte *gmap, imbyte *bmap, int maxcol)
+{
+/* scans picture until it finds more than 'maxcol' different colors. If it
+finds more than 'maxcol' colors, it returns '0'. If it DOESN'T, it does
+the 24-to-8 conversion by simply sticking the colors it found into
+a colormap, and changing instances of a color in pic24 into colormap
+ indicies (in pic8) */
+
+ unsigned long colors[256],col;
+ int i, nc, low, high, mid, count;
+ imbyte *pred, *pgreen, *pblue, *pix;
+
+ if (maxcol>256) maxcol = 256;
+
+ /* put the first color in the table by hand */
+ nc = 0; mid = 0;
+
+ count = w*h;
+ for (i=count,pred=red,pgreen=green,pblue=blue; i; i--)
+ {
+ col = (((unsigned long) *pred++) << 16);
+ col += (((unsigned long) *pgreen++) << 8);
+ col += *pblue++;
+
+ /* binary search the 'colors' array to see if it's in there */
+ low = 0; high = nc-1;
+ while (low <= high)
+ {
+ mid = (low+high)/2;
+ if (col < colors[mid]) high = mid - 1;
+ else if (col > colors[mid]) low = mid + 1;
+ else break;
+ }
+
+ if (high < low)
+ { /* didn't find color in list, add it. */
+ if (nc>=maxcol)
+ return 0;
+
+ xvbcopy((const imbyte*)&colors[low], (imbyte*)&colors[low+1], (nc - low) * sizeof(unsigned long));
+ colors[low] = col;
+ nc++;
+ }
+ }
+
+ /* run through the data a second time, this time mapping pixel values in
+ pic24 into colormap offsets into 'colors' */
+
+ for (i=count,pred=red,pgreen=green,pblue=blue, pix=map; i; i--,pix++)
+ {
+ col = (((unsigned long) *pred++) << 16);
+ col += (((unsigned long) *pgreen++) << 8);
+ col += *pblue++;
+
+ /* binary search the 'colors' array. It *IS* in there */
+ low = 0; high = nc-1;
+ while (low <= high)
+ {
+ mid = (low+high)/2;
+ if (col < colors[mid]) high = mid - 1;
+ else if (col > colors[mid]) low = mid + 1;
+ else break;
+ }
+
+ if (high < low)
+ return 0;
+
+ *pix = (imbyte)mid;
+ }
+
+ /* and load up the 'desired colormap' */
+ for (i=0; i<nc; i++)
+ {
+ rmap[i] = (unsigned char)( colors[i]>>16);
+ gmap[i] = (unsigned char)((colors[i]>>8) & 0xff);
+ bmap[i] = (unsigned char)( colors[i] & 0xff);
+ }
+
+ return nc;
+}
+
+#define MAXNUMCOLORS 256 /* maximum size of colormap */
+
+#define C0_SCALE 2 /* scale R distances by this much */
+#define C1_SCALE 3 /* scale G distances by this much */
+#define C2_SCALE 1 /* and B by this much */
+
+#define HIST_C0_BITS 5 /* bits of precision in R histogram */
+#define HIST_C1_BITS 6 /* bits of precision in G histogram */
+#define HIST_C2_BITS 5 /* bits of precision in B histogram */
+
+/* Number of elements along histogram axes. */
+#define HIST_C0_ELEMS (1<<HIST_C0_BITS)
+#define HIST_C1_ELEMS (1<<HIST_C1_BITS)
+#define HIST_C2_ELEMS (1<<HIST_C2_BITS)
+
+/* These are the amounts to shift an input value to get a histogram index. */
+#define C0_SHIFT (8-HIST_C0_BITS)
+#define C1_SHIFT (8-HIST_C1_BITS)
+#define C2_SHIFT (8-HIST_C2_BITS)
+
+
+typedef imushort histcell; /* histogram cell; prefer an unsigned type */
+
+typedef histcell * histptr; /* for pointers to histogram cells */
+
+typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the histogram array */
+typedef hist1d hist2d[HIST_C1_ELEMS];
+typedef hist2d hist3d[HIST_C0_ELEMS];
+
+typedef short FSERROR; /* 16 bits should be enough */
+typedef int LOCFSERROR; /* use 'int' for calculation temps */
+
+typedef FSERROR *FSERRPTR; /* pointer to error array */
+
+typedef struct {
+ /* The bounds of the box (inclusive); expressed as histogram indexes */
+ int c0min, c0max;
+ int c1min, c1max;
+ int c2min, c2max;
+ /* The volume (actually 2-norm) of the box */
+ int volume;
+ /* The number of nonzero histogram cells within this box */
+ long colorcount;
+} box;
+typedef box * boxptr;
+
+/* Local state for the IJG quantizer */
+
+static hist2d * sl_histogram; /* pointer to the 3D histogram array */
+static FSERRPTR sl_fserrors; /* accumulated-errors array */
+static int * sl_error_limiter; /* table for clamping the applied error */
+static int sl_on_odd_row; /* flag to remember which row we are on */
+static imbyte* sl_colormap[3]; /* selected colormap */
+static int sl_num_colors; /* number of selected colors */
+
+
+static void slow_fill_histogram (imbyte*, imbyte*, imbyte*, int);
+static boxptr find_biggest_color_pop (boxptr, int);
+static boxptr find_biggest_volume (boxptr, int);
+static void update_box (boxptr);
+static int median_cut (boxptr, int, int);
+static void compute_color (boxptr, int);
+static void slow_select_colors (int);
+static int find_nearby_colors (int, int, int, imbyte []);
+static void find_best_colors (int,int,int,int, imbyte [], imbyte []);
+static void fill_inverse_cmap (int, int, int);
+static void slow_map_pixels (imbyte*, imbyte*, imbyte*, int, int, imbyte*);
+static void init_error_limit (void);
+
+
+/* Master control for slow quantizer. */
+static int slow_quant(imbyte *red, imbyte *green, imbyte *blue, int w, int h, imbyte *map,
+ imbyte *rm, imbyte *gm, imbyte *bm, int descols)
+{
+ size_t fs_arraysize = (w + 2) * (3 * sizeof(FSERROR));
+
+ /* Allocate all the temporary storage needed */
+ init_error_limit();
+
+ sl_histogram = (hist2d *) malloc(sizeof(hist3d));
+ sl_fserrors = (FSERRPTR) malloc(fs_arraysize);
+
+ if (! sl_error_limiter || ! sl_histogram || ! sl_fserrors)
+ {
+ if (sl_error_limiter) free(sl_error_limiter-255);
+ if (sl_fserrors) free(sl_fserrors);
+ if (sl_histogram) free(sl_histogram);
+ return 1;
+ }
+
+ sl_colormap[0] = (imbyte*) rm;
+ sl_colormap[1] = (imbyte*) gm;
+ sl_colormap[2] = (imbyte*) bm;
+
+ /* Compute the color histogram */
+ slow_fill_histogram(red, green, blue, w*h);
+
+ /* Select the colormap */
+ slow_select_colors(descols);
+
+ /* Zero the histogram: now to be used as inverse color map */
+ memset(sl_histogram, 0, sizeof(hist3d));
+
+ /* Initialize the propagated errors to zero. */
+ memset(sl_fserrors, 0, fs_arraysize);
+ sl_on_odd_row = 0;
+
+ /* Map the image. */
+ slow_map_pixels(red, green, blue, w, h, map);
+
+ /* Release working memory. */
+ free(sl_histogram);
+ free(sl_error_limiter-255);
+ free(sl_fserrors);
+
+ return 0;
+}
+
+
+static void slow_fill_histogram (register imbyte *red, register imbyte *green, register imbyte *blue, int numpixels)
+{
+ register histptr histp;
+ register hist2d * histogram = sl_histogram;
+
+ memset(histogram, 0, sizeof(hist3d));
+
+ while (numpixels-- > 0)
+ {
+ /* get pixel value and index into the histogram */
+ histp = & histogram[*red >> C0_SHIFT] [*green >> C1_SHIFT] [*blue >> C2_SHIFT];
+
+ /* increment, check for overflow and undo increment if so. */
+ if (++(*histp) <= 0)
+ (*histp)--;
+
+ red++;
+ green++;
+ blue++;
+ }
+}
+
+
+static boxptr find_biggest_color_pop (boxptr boxlist, int numboxes)
+{
+ register boxptr boxp;
+ register int i;
+ register long maxc = 0;
+ boxptr which = NULL;
+
+ for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+ if (boxp->colorcount > maxc && boxp->volume > 0) {
+ which = boxp;
+ maxc = boxp->colorcount;
+ }
+ }
+ return which;
+}
+
+static boxptr find_biggest_volume (boxptr boxlist, int numboxes)
+{
+ register boxptr boxp;
+ register int i;
+ register int maxv = 0;
+ boxptr which = NULL;
+
+ for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+ if (boxp->volume > maxv) {
+ which = boxp;
+ maxv = boxp->volume;
+ }
+ }
+ return which;
+}
+
+
+static void update_box (boxptr boxp)
+{
+ hist2d * histogram = sl_histogram;
+ histptr histp;
+ int c0,c1,c2;
+ int c0min,c0max,c1min,c1max,c2min,c2max;
+ int dist0,dist1,dist2;
+ long ccount;
+
+ c0min = boxp->c0min; c0max = boxp->c0max;
+ c1min = boxp->c1min; c1max = boxp->c1max;
+ c2min = boxp->c2min; c2max = boxp->c2max;
+
+ if (c0max > c0min)
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c0min = c0min = c0;
+ goto have_c0min;
+ }
+ }
+have_c0min:
+ if (c0max > c0min)
+ for (c0 = c0max; c0 >= c0min; c0--)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c0max = c0max = c0;
+ goto have_c0max;
+ }
+ }
+have_c0max:
+ if (c1max > c1min)
+ for (c1 = c1min; c1 <= c1max; c1++)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c1min = c1min = c1;
+ goto have_c1min;
+ }
+ }
+have_c1min:
+ if (c1max > c1min)
+ for (c1 = c1max; c1 >= c1min; c1--)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c1max = c1max = c1;
+ goto have_c1max;
+ }
+ }
+have_c1max:
+ if (c2max > c2min)
+ for (c2 = c2min; c2 <= c2max; c2++)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1min][c2];
+ for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+ if (*histp != 0) {
+ boxp->c2min = c2min = c2;
+ goto have_c2min;
+ }
+ }
+have_c2min:
+ if (c2max > c2min)
+ for (c2 = c2max; c2 >= c2min; c2--)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1min][c2];
+ for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+ if (*histp != 0) {
+ boxp->c2max = c2max = c2;
+ goto have_c2max;
+ }
+ }
+have_c2max:
+
+ dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
+ dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
+ dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
+ boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
+
+ ccount = 0;
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++, histp++)
+ if (*histp != 0) {
+ ccount++;
+ }
+ }
+ boxp->colorcount = ccount;
+}
+
+
+static int median_cut (boxptr boxlist, int numboxes, int desired_colors)
+{
+ int n,lb;
+ int c0,c1,c2,cmax;
+ register boxptr b1,b2;
+
+ while (numboxes < desired_colors) {
+ /* Select box to split.
+ * Current algorithm: by population for first half, then by volume.
+ */
+ if (numboxes*2 <= desired_colors) {
+ b1 = find_biggest_color_pop(boxlist, numboxes);
+ } else {
+ b1 = find_biggest_volume(boxlist, numboxes);
+ }
+ if (b1 == NULL) /* no splittable boxes left! */
+ break;
+ b2 = &boxlist[numboxes]; /* where new box will go */
+ /* Copy the color bounds to the new box. */
+ b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
+ b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
+ /* Choose which axis to split the box on.
+ */
+ c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
+ c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
+ c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
+ cmax = c1; n = 1;
+ if (c0 > cmax) { cmax = c0; n = 0; }
+ if (c2 > cmax) { n = 2; }
+ switch (n) {
+ case 0:
+ lb = (b1->c0max + b1->c0min) / 2;
+ b1->c0max = lb;
+ b2->c0min = lb+1;
+ break;
+ case 1:
+ lb = (b1->c1max + b1->c1min) / 2;
+ b1->c1max = lb;
+ b2->c1min = lb+1;
+ break;
+ case 2:
+ lb = (b1->c2max + b1->c2min) / 2;
+ b1->c2max = lb;
+ b2->c2min = lb+1;
+ break;
+ }
+ /* Update stats for boxes */
+ update_box(b1);
+ update_box(b2);
+ numboxes++;
+ }
+ return numboxes;
+}
+
+static void compute_color (boxptr boxp, int icolor)
+{
+ /* Current algorithm: mean weighted by pixels (not colors) */
+ /* Note it is important to get the rounding correct! */
+ hist2d * histogram = sl_histogram;
+ histptr histp;
+ int c0,c1,c2;
+ int c0min,c0max,c1min,c1max,c2min,c2max;
+ long count;
+ long total = 0;
+ long c0total = 0;
+ long c1total = 0;
+ long c2total = 0;
+
+ c0min = boxp->c0min; c0max = boxp->c0max;
+ c1min = boxp->c1min; c1max = boxp->c1max;
+ c2min = boxp->c2min; c2max = boxp->c2max;
+
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++) {
+ if ((count = *histp++) != 0) {
+ total += count;
+ c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count;
+ c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count;
+ c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count;
+ }
+ }
+ }
+
+ sl_colormap[0][icolor] = (imbyte) ((c0total + (total>>1)) / total);
+ sl_colormap[1][icolor] = (imbyte) ((c1total + (total>>1)) / total);
+ sl_colormap[2][icolor] = (imbyte) ((c2total + (total>>1)) / total);
+}
+
+
+static void slow_select_colors (int descolors)
+/* Master routine for color selection */
+{
+ box boxlist[MAXNUMCOLORS];
+ int numboxes;
+ int i;
+
+ /* Initialize one box containing whole space */
+ numboxes = 1;
+ boxlist[0].c0min = 0;
+ boxlist[0].c0max = 255 >> C0_SHIFT;
+ boxlist[0].c1min = 0;
+ boxlist[0].c1max = 255 >> C1_SHIFT;
+ boxlist[0].c2min = 0;
+ boxlist[0].c2max = 255 >> C2_SHIFT;
+ /* Shrink it to actually-used volume and set its statistics */
+ update_box(& boxlist[0]);
+ /* Perform median-cut to produce final box list */
+ numboxes = median_cut(boxlist, numboxes, descolors);
+ /* Compute the representative color for each box, fill colormap */
+ for (i = 0; i < numboxes; i++)
+ compute_color(& boxlist[i], i);
+ sl_num_colors = numboxes;
+}
+
+
+/* log2(histogram cells in update box) for each axis; this can be adjusted */
+#define BOX_C0_LOG (HIST_C0_BITS-3)
+#define BOX_C1_LOG (HIST_C1_BITS-3)
+#define BOX_C2_LOG (HIST_C2_BITS-3)
+
+#define BOX_C0_ELEMS (1<<BOX_C0_LOG) /* # of hist cells in update box */
+#define BOX_C1_ELEMS (1<<BOX_C1_LOG)
+#define BOX_C2_ELEMS (1<<BOX_C2_LOG)
+
+#define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG)
+#define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG)
+#define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG)
+
+
+static int find_nearby_colors (int minc0, int minc1, int minc2, imbyte* colorlist)
+{
+ int numcolors = sl_num_colors;
+ int maxc0, maxc1, maxc2;
+ int centerc0, centerc1, centerc2;
+ int i, x, ncolors;
+ int minmaxdist, min_dist, max_dist, tdist;
+ int mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */
+
+ maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
+ centerc0 = (minc0 + maxc0) >> 1;
+ maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
+ centerc1 = (minc1 + maxc1) >> 1;
+ maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
+ centerc2 = (minc2 + maxc2) >> 1;
+
+ minmaxdist = 0x7FFFFFFFL;
+
+ for (i = 0; i < numcolors; i++) {
+ /* We compute the squared-c0-distance term, then add in the other two. */
+ x = sl_colormap[0][i];
+ if (x < minc0) {
+ tdist = (x - minc0) * C0_SCALE;
+ min_dist = tdist*tdist;
+ tdist = (x - maxc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else if (x > maxc0) {
+ tdist = (x - maxc0) * C0_SCALE;
+ min_dist = tdist*tdist;
+ tdist = (x - minc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ min_dist = 0;
+ if (x <= centerc0) {
+ tdist = (x - maxc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else {
+ tdist = (x - minc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ }
+ }
+
+ x = sl_colormap[1][i];
+ if (x < minc1) {
+ tdist = (x - minc1) * C1_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - maxc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else if (x > maxc1) {
+ tdist = (x - maxc1) * C1_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - minc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ if (x <= centerc1) {
+ tdist = (x - maxc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ tdist = (x - minc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ }
+ }
+
+ x = sl_colormap[2][i];
+ if (x < minc2) {
+ tdist = (x - minc2) * C2_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - maxc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else if (x > maxc2) {
+ tdist = (x - maxc2) * C2_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - minc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ if (x <= centerc2) {
+ tdist = (x - maxc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ tdist = (x - minc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ }
+ }
+
+ mindist[i] = min_dist; /* save away the results */
+ if (max_dist < minmaxdist)
+ minmaxdist = max_dist;
+ }
+
+ ncolors = 0;
+ for (i = 0; i < numcolors; i++) {
+ if (mindist[i] <= minmaxdist)
+ colorlist[ncolors++] = (imbyte) i;
+ }
+ return ncolors;
+}
+
+
+static void find_best_colors (int minc0, int minc1, int minc2, int numcolors,
+ imbyte* colorlist, imbyte* bestcolor)
+{
+ int ic0, ic1, ic2;
+ int i, icolor;
+ register int * bptr; /* pointer into bestdist[] array */
+ imbyte * cptr; /* pointer into bestcolor[] array */
+ int dist0, dist1; /* initial distance values */
+ register int dist2; /* current distance in inner loop */
+ int xx0, xx1; /* distance increments */
+ register int xx2;
+ int inc0, inc1, inc2; /* initial values for increments */
+ /* This array holds the distance to the nearest-so-far color for each cell */
+ int bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+ /* Initialize best-distance for each cell of the update box */
+ bptr = bestdist;
+ for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
+ *bptr++ = 0x7FFFFFFFL;
+
+ /* Nominal steps between cell centers ("x" in Thomas article) */
+#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE)
+#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE)
+#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
+
+ for (i = 0; i < numcolors; i++) {
+ icolor = colorlist[i];
+ /* Compute (square of) distance from minc0/c1/c2 to this color */
+ inc0 = (minc0 - (int) sl_colormap[0][icolor]) * C0_SCALE;
+ dist0 = inc0*inc0;
+ inc1 = (minc1 - (int) sl_colormap[1][icolor]) * C1_SCALE;
+ dist0 += inc1*inc1;
+ inc2 = (minc2 - (int) sl_colormap[2][icolor]) * C2_SCALE;
+ dist0 += inc2*inc2;
+ /* Form the initial difference increments */
+ inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
+ inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
+ inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
+ /* Now loop over all cells in box, updating distance per Thomas method */
+ bptr = bestdist;
+ cptr = bestcolor;
+ xx0 = inc0;
+ for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
+ dist1 = dist0;
+ xx1 = inc1;
+ for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
+ dist2 = dist1;
+ xx2 = inc2;
+ for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
+ if (dist2 < *bptr) {
+ *bptr = dist2;
+ *cptr = (imbyte) icolor;
+ }
+ dist2 += xx2;
+ xx2 += 2 * STEP_C2 * STEP_C2;
+ bptr++;
+ cptr++;
+ }
+ dist1 += xx1;
+ xx1 += 2 * STEP_C1 * STEP_C1;
+ }
+ dist0 += xx0;
+ xx0 += 2 * STEP_C0 * STEP_C0;
+ }
+ }
+}
+
+
+static void fill_inverse_cmap (int c0, int c1, int c2)
+{
+ hist2d * histogram = sl_histogram;
+ int minc0, minc1, minc2; /* lower left corner of update box */
+ int ic0, ic1, ic2;
+ register imbyte * cptr; /* pointer into bestcolor[] array */
+ register histptr cachep; /* pointer into main cache array */
+ /* This array lists the candidate colormap indexes. */
+ imbyte colorlist[MAXNUMCOLORS];
+ int numcolors; /* number of candidate colors */
+ /* This array holds the actually closest colormap index for each cell. */
+ imbyte bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+ /* Convert cell coordinates to update box ID */
+ c0 >>= BOX_C0_LOG;
+ c1 >>= BOX_C1_LOG;
+ c2 >>= BOX_C2_LOG;
+
+ minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
+ minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
+ minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
+
+ numcolors = find_nearby_colors(minc0, minc1, minc2, colorlist);
+
+ /* Determine the actually nearest colors. */
+ find_best_colors(minc0, minc1, minc2, numcolors, colorlist, bestcolor);
+
+ /* Save the best color numbers (plus 1) in the main cache array */
+ c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */
+ c1 <<= BOX_C1_LOG;
+ c2 <<= BOX_C2_LOG;
+ cptr = bestcolor;
+ for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
+ for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
+ cachep = & histogram[c0+ic0][c1+ic1][c2];
+ for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
+ *cachep++ = (histcell) (*cptr++ + 1);
+ }
+ }
+ }
+}
+
+
+static void slow_map_pixels (imbyte *red, imbyte *green, imbyte *blue, int width, int height, imbyte *map)
+{
+ register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */
+ LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
+ LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
+ register FSERRPTR errorptr; /* => fserrors[] at column before current */
+ imbyte *inRptr, *inGptr, *inBptr; /* => current input pixel */
+ imbyte* outptr; /* => current output pixel */
+ histptr cachep;
+ int dir; /* +1 or -1 depending on direction */
+ int dir3; /* 3*dir, for advancing errorptr */
+ int row, col, offset;
+ int *error_limit = sl_error_limiter;
+ imbyte* colormap0 = sl_colormap[0];
+ imbyte* colormap1 = sl_colormap[1];
+ imbyte* colormap2 = sl_colormap[2];
+ hist2d * histogram = sl_histogram;
+
+ for (row = 0; row < height; row++)
+ {
+ offset = row * width;
+
+ inRptr = & red[offset];
+ inGptr = & green[offset];
+ inBptr = & blue[offset];
+ outptr = & map[offset];
+
+ if (sl_on_odd_row)
+ {
+ /* work right to left in this row */
+ offset = width-1;
+
+ inRptr += offset; /* so point to rightmost pixel */
+ inGptr += offset; /* so point to rightmost pixel */
+ inBptr += offset; /* so point to rightmost pixel */
+
+ outptr += offset;
+
+ dir = -1;
+ dir3 = -3;
+ errorptr = sl_fserrors + (width+1)*3; /* => entry after last column */
+ sl_on_odd_row = 0; /* flip for next time */
+ }
+ else
+ {
+ /* work left to right in this row */
+ dir = 1;
+ dir3 = 3;
+ errorptr = sl_fserrors; /* => entry before first real column */
+ sl_on_odd_row = 1; /* flip for next time */
+ }
+
+ /* Preset error values: no error propagated to first pixel from left */
+ cur0 = cur1 = cur2 = 0;
+ /* and no error propagated to row below yet */
+ belowerr0 = belowerr1 = belowerr2 = 0;
+ bpreverr0 = bpreverr1 = bpreverr2 = 0;
+
+ for (col = width; col > 0; col--)
+ {
+ cur0 = (cur0 + errorptr[dir3+0] + 8) >> 4;
+ cur1 = (cur1 + errorptr[dir3+1] + 8) >> 4;
+ cur2 = (cur2 + errorptr[dir3+2] + 8) >> 4;
+
+ cur0 = error_limit[cur0];
+ cur1 = error_limit[cur1];
+ cur2 = error_limit[cur2];
+
+ cur0 += inRptr[0];
+ cur1 += inGptr[0];
+ cur2 += inBptr[0];
+
+ RANGE(cur0, 0, 255);
+ RANGE(cur1, 0, 255);
+ RANGE(cur2, 0, 255);
+
+ /* Index into the cache with adjusted pixel value */
+ cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
+
+ /* If we have not seen this color before, find nearest colormap */
+ /* entry and update the cache */
+ if (*cachep == 0)
+ fill_inverse_cmap(cur0>>C0_SHIFT, cur1>>C1_SHIFT, cur2>>C2_SHIFT);
+
+ /* Now emit the colormap index for this cell */
+ {
+ register int pixcode = *cachep - 1;
+ *outptr = (imbyte) pixcode;
+ /* Compute representation error for this pixel */
+ cur0 -= (int) colormap0[pixcode];
+ cur1 -= (int) colormap1[pixcode];
+ cur2 -= (int) colormap2[pixcode];
+ }
+
+ /* Compute error fractions to be propagated to adjacent pixels.
+ * Add these into the running sums, and simultaneously shift the
+ * next-line error sums left by 1 column. */
+ {
+ register LOCFSERROR bnexterr, delta;
+ bnexterr = cur0; /* Process component 0 */
+ delta = cur0 * 2;
+ cur0 += delta; /* form error * 3 */
+ errorptr[0] = (FSERROR) (bpreverr0 + cur0);
+ cur0 += delta; /* form error * 5 */
+ bpreverr0 = belowerr0 + cur0;
+ belowerr0 = bnexterr;
+ cur0 += delta; /* form error * 7 */
+ bnexterr = cur1; /* Process component 1 */
+ delta = cur1 * 2;
+ cur1 += delta; /* form error * 3 */
+ errorptr[1] = (FSERROR) (bpreverr1 + cur1);
+ cur1 += delta; /* form error * 5 */
+ bpreverr1 = belowerr1 + cur1;
+ belowerr1 = bnexterr;
+ cur1 += delta; /* form error * 7 */
+ bnexterr = cur2; /* Process component 2 */
+ delta = cur2 * 2;
+ cur2 += delta; /* form error * 3 */
+ errorptr[2] = (FSERROR) (bpreverr2 + cur2);
+ cur2 += delta; /* form error * 5 */
+ bpreverr2 = belowerr2 + cur2;
+ belowerr2 = bnexterr;
+ cur2 += delta; /* form error * 7 */
+ }
+
+ /* At this point curN contains the 7/16 error value to be propagated
+ * to the next pixel on the current line, and all the errors for the
+ * next line have been shifted over. We are therefore ready to move on.
+ */
+ inRptr += dir; /* Advance pixel pointers to next column */
+ inGptr += dir; /* Advance pixel pointers to next column */
+ inBptr += dir; /* Advance pixel pointers to next column */
+ outptr += dir;
+ errorptr += dir3; /* advance errorptr to current column */
+ }
+
+ /* Post-loop cleanup: we must unload the final error values into the
+ * final fserrors[] entry. Note we need not unload belowerrN because
+ * it is for the dummy column before or after the actual array.
+ */
+ errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
+ errorptr[1] = (FSERROR) bpreverr1;
+ errorptr[2] = (FSERROR) bpreverr2;
+ }
+}
+
+
+/* Allocate and fill in the error_limiter table */
+static void init_error_limit (void)
+{
+ int * table;
+ int in, out, STEPSIZE;
+
+ table = (int *) malloc((size_t) ((255*2+1) * sizeof(int)));
+ if (! table) return;
+
+ table += 255; /* so can index -255 .. +255 */
+ sl_error_limiter = table;
+
+ STEPSIZE = ((255+1)/16);
+
+ /* Map errors 1:1 up to +- 255/16 */
+ out = 0;
+ for (in = 0; in < STEPSIZE; in++, out++)
+ {
+ table[in] = out;
+ table[-in] = -out;
+ }
+
+ /* Map errors 1:2 up to +- 3*255/16 */
+ for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1)
+ {
+ table[in] = out;
+ table[-in] = -out;
+ }
+
+ /* Clamp the rest to final out value (which is (255+1)/8) */
+ for (; in <= 255; in++)
+ {
+ table[in] = out;
+ table[-in] = -out;
+ }
+}
+
+int imConvertRGB2Map(int width, int height, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *map, long *palette, int *palette_count)
+{
+ int i, err, new_palette_count;
+ imbyte rm[256], gm[256], bm[256];
+
+ if (*palette_count <= 0 || *palette_count > 256)
+ *palette_count = 256;
+
+ new_palette_count = quick_map(red, green, blue, width, height, map, rm, gm, bm, *palette_count);
+ if (new_palette_count)
+ {
+ for (i=0; i < new_palette_count; i++)
+ *palette++ = imColorEncode(rm[i], gm[i], bm[i]);
+
+ *palette_count = new_palette_count;
+ return IM_ERR_NONE;
+ }
+
+ err = slow_quant(red, green, blue, width, height, map, rm, gm, bm, *palette_count);
+ if (err)
+ return IM_ERR_MEM;
+
+ for (i=0; i < *palette_count; i++)
+ *palette++ = imColorEncode(rm[i], gm[i], bm[i]);
+
+ return IM_ERR_NONE;
+}
+
diff --git a/im/src/im_str.cpp b/im/src/im_str.cpp
new file mode 100755
index 0000000..f50dcf1
--- /dev/null
+++ b/im/src/im_str.cpp
@@ -0,0 +1,67 @@
+/** \file
+ * \brief String Utilities
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_str.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+
+#include <stdlib.h>
+#include <memory.h>
+#include <assert.h>
+
+#include "im_util.h"
+
+int imStrEqual(const char* str1, const char* str2)
+{
+ assert(str1);
+ assert(str2);
+
+ /* While both strings are equal and not 0 */
+ while (*str1 == *str2 && *str1)
+ {
+ str1++;
+ str2++;
+ }
+
+ /* Is last char not equal ? */
+ if (*str1 != *str2)
+ return 0;
+
+ return 1;
+}
+
+int imStrNLen(const char* str, int max_len)
+{
+ assert(str);
+
+ const char* start_str = str;
+
+ while(max_len && *str)
+ {
+ max_len--;
+ str++;
+ }
+
+ return str - start_str;
+}
+
+int imStrCheck(const void* data, int count)
+{
+ const char* str = (char*)data;
+
+ if (str[count-1] == 0)
+ return 1;
+
+ while(count && *str)
+ {
+ count--;
+ str++;
+ }
+
+ if (count > 0)
+ return 1;
+
+ return 0;
+}
+
diff --git a/im/src/im_sysfile_unix.cpp b/im/src/im_sysfile_unix.cpp
new file mode 100755
index 0000000..2065bb6
--- /dev/null
+++ b/im/src/im_sysfile_unix.cpp
@@ -0,0 +1,211 @@
+/** \file
+ * \brief System Dependent Binary File Access (UNIX)
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_sysfile_unix.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "im_util.h"
+#include "im_binfile.h"
+
+
+class imBinSystemFile: public imBinFileBase
+{
+protected:
+ int FileHandle,
+ Error;
+
+ unsigned long ReadBuf(void* pValues, unsigned long pSize);
+ unsigned long WriteBuf(void* pValues, unsigned long pSize);
+
+public:
+ virtual void Open(const char* pFileName);
+ virtual void New(const char* pFileName);
+ virtual void Close();
+
+ unsigned long FileSize();
+ int HasError() const;
+ void SeekTo(unsigned long pOffset);
+ void SeekOffset(long pOffset);
+ void SeekFrom(long pOffset);
+ unsigned long Tell() const;
+ int EndOfFile() const;
+};
+
+imBinFileBase* iBinSystemFileNewFunc()
+{
+ return new imBinSystemFile();
+}
+
+void imBinSystemFile::Open(const char* pFileName)
+{
+ int mode = O_RDONLY;
+#ifdef O_BINARY
+ mode |= O_BINARY;
+#endif
+ this->FileHandle = open(pFileName, mode, 0);
+ if (this->FileHandle < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 0;
+}
+
+void imBinSystemFile::New(const char* pFileName)
+{
+ int mode = O_WRONLY | O_CREAT | O_TRUNC;
+#ifdef O_BINARY
+ mode |= O_BINARY;
+#endif
+ this->FileHandle = open(pFileName, mode, 0666); // User/Group/Other can read and write
+ if (this->FileHandle < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 1;
+}
+
+void imBinSystemFile::Close()
+{
+ assert(this->FileHandle > -1);
+ int ret = close(this->FileHandle);
+ if (ret < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+}
+
+int imBinSystemFile::HasError() const
+{
+ if (this->FileHandle < 0 || this->Error) return 1;
+ return 0;
+}
+
+unsigned long imBinSystemFile::ReadBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle > -1);
+ int ret = read(this->FileHandle, pValues, (size_t)pSize);
+ if (ret < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+ return ret < 0? 0: ret;
+}
+
+unsigned long imBinSystemFile::WriteBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle > -1);
+ int ret = write(this->FileHandle, pValues, (size_t)pSize);
+ if (ret < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+ return ret < 0? 0: ret;
+}
+
+void imBinSystemFile::SeekTo(unsigned long pOffset)
+{
+ assert(this->FileHandle > -1);
+ int ret = lseek(this->FileHandle, pOffset, SEEK_SET);
+ if (ret < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+}
+
+void imBinSystemFile::SeekOffset(long pOffset)
+{
+ assert(this->FileHandle > -1);
+ int ret = lseek(this->FileHandle, pOffset, SEEK_CUR);
+ if (ret < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+}
+
+void imBinSystemFile::SeekFrom(long pOffset)
+{
+ assert(this->FileHandle > -1);
+ int ret = lseek(this->FileHandle, pOffset, SEEK_END);
+ if (ret < 0)
+ this->Error = errno;
+ else
+ this->Error = 0;
+}
+
+unsigned long imBinSystemFile::Tell() const
+{
+ assert(this->FileHandle > -1);
+ long offset = lseek(this->FileHandle, 0L, SEEK_CUR);
+ return offset < 0? 0: offset;
+}
+
+unsigned long imBinSystemFile::FileSize()
+{
+ assert(this->FileHandle > -1);
+ long lCurrentPosition = lseek(this->FileHandle, 0L, SEEK_CUR);
+ long lSize = lseek(this->FileHandle, 0L, SEEK_END);
+ lseek(this->FileHandle, lCurrentPosition, SEEK_SET);
+ return lSize < 0? 0: lSize;
+}
+
+int imBinSystemFile::EndOfFile() const
+{
+ assert(this->FileHandle > -1);
+ long lCurrentPosition = lseek(this->FileHandle, 0L, SEEK_CUR);
+ long lSize = lseek(this->FileHandle, 0L, SEEK_END);
+ lseek(this->FileHandle, lCurrentPosition, SEEK_SET);
+ return lCurrentPosition == lSize? 1: 0;
+}
+
+
+
+class imBinSystemFileHandle: public imBinSystemFile
+{
+public:
+ virtual void Open(const char* pFileName);
+ virtual void New(const char* pFileName);
+ virtual void Close();
+};
+
+imBinFileBase* iBinSystemFileHandleNewFunc()
+{
+ return new imBinSystemFileHandle();
+}
+
+void imBinSystemFileHandle::Open(const char* pFileName)
+{
+ // the file was successfully opened already by the client
+
+ int *s = (int*)pFileName;
+ this->FileHandle = s[0];
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 0;
+ this->Error = 0;
+}
+
+void imBinSystemFileHandle::New(const char* pFileName)
+{
+ // the file was successfully opened already the client
+
+ int *s = (int*)pFileName;
+ this->FileHandle = s[0];
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 1;
+ this->Error = 0;
+}
+
+void imBinSystemFileHandle::Close()
+{
+ // does nothing, the client must close the file
+}
diff --git a/im/src/im_sysfile_win32.cpp b/im/src/im_sysfile_win32.cpp
new file mode 100755
index 0000000..1daf85b
--- /dev/null
+++ b/im/src/im_sysfile_win32.cpp
@@ -0,0 +1,207 @@
+/** \file
+ * \brief System Dependent Binary File Access.
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_sysfile_win32.cpp,v 1.2 2009/10/01 16:12:24 scuri Exp $
+ */
+
+#include <windows.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <assert.h>
+
+#include "im_util.h"
+#include "im_binfile.h"
+
+/* not defined in VC6 */
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
+class imBinSystemFile: public imBinFileBase
+{
+protected:
+ HANDLE FileHandle;
+ int Error;
+
+ unsigned long ReadBuf(void* pValues, unsigned long pSize);
+ unsigned long WriteBuf(void* pValues, unsigned long pSize);
+
+public:
+ virtual void Open(const char* pFileName);
+ virtual void New(const char* pFileName);
+ virtual void Close();
+
+ unsigned long FileSize();
+ int HasError() const;
+ void SeekTo(unsigned long pOffset);
+ void SeekOffset(long pOffset);
+ void SeekFrom(long pOffset);
+ unsigned long Tell() const;
+ int EndOfFile() const;
+};
+
+imBinFileBase* iBinSystemFileNewFunc()
+{
+ return new imBinSystemFile();
+}
+
+void imBinSystemFile::Open(const char* pFileName)
+{
+ this->FileHandle = CreateFile(pFileName, GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ this->Error = (this->FileHandle == INVALID_HANDLE_VALUE)? 1: 0;
+ SetLastError(NO_ERROR);
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 0;
+}
+
+void imBinSystemFile::New(const char* pFileName)
+{
+ this->FileHandle = CreateFile(pFileName, GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ this->Error = (this->FileHandle == INVALID_HANDLE_VALUE)? 1: 0;
+ SetLastError(NO_ERROR);
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 1;
+}
+
+void imBinSystemFile::Close()
+{
+ if (this->FileHandle != INVALID_HANDLE_VALUE)
+ CloseHandle(this->FileHandle);
+
+ this->FileHandle = INVALID_HANDLE_VALUE;
+ this->Error = 1;
+}
+
+unsigned long imBinSystemFile::FileSize()
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ this->Error = 0;
+ DWORD Size = GetFileSize(this->FileHandle, NULL);
+ if (Size == INVALID_FILE_SIZE)
+ this->Error = 1;
+ return Size;
+}
+
+unsigned long imBinSystemFile::ReadBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ this->Error = 0;
+ DWORD dwSize = 0;
+ ReadFile(this->FileHandle, pValues, pSize, &dwSize, NULL);
+ if (dwSize != pSize)
+ this->Error = 1;
+ return dwSize;
+}
+
+unsigned long imBinSystemFile::WriteBuf(void* pValues, unsigned long pSize)
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ this->Error = 0;
+ DWORD dwSize = 0;
+ WriteFile(this->FileHandle, pValues, pSize, &dwSize, NULL);
+ if (dwSize != pSize)
+ this->Error = 1;
+ return dwSize;
+}
+
+int imBinSystemFile::HasError() const
+{
+ return this->Error;
+}
+
+void imBinSystemFile::SeekTo(unsigned long pOffset)
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ this->Error = 0;
+ DWORD ret = SetFilePointer(this->FileHandle, pOffset, NULL, FILE_BEGIN);
+ if (ret == INVALID_SET_FILE_POINTER)
+ this->Error = 1;
+}
+
+void imBinSystemFile::SeekOffset(long pOffset)
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ this->Error = 0;
+ DWORD ret = SetFilePointer(this->FileHandle, pOffset, NULL, FILE_CURRENT);
+ if (ret == INVALID_SET_FILE_POINTER)
+ this->Error = 1;
+}
+
+void imBinSystemFile::SeekFrom(long pOffset)
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ this->Error = 0;
+ DWORD ret = SetFilePointer(this->FileHandle, pOffset, NULL, FILE_END);
+ if (ret == INVALID_SET_FILE_POINTER)
+ this->Error = 1;
+}
+
+unsigned long imBinSystemFile::Tell() const
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ return SetFilePointer(this->FileHandle, 0, NULL, FILE_CURRENT);
+}
+
+int imBinSystemFile::EndOfFile() const
+{
+ assert(this->FileHandle != INVALID_HANDLE_VALUE);
+ DWORD cur_pos = SetFilePointer(this->FileHandle, 0, NULL, FILE_CURRENT);
+ DWORD end_pos = SetFilePointer(this->FileHandle, 0, NULL, FILE_END);
+ SetFilePointer(this->FileHandle, cur_pos, NULL, FILE_CURRENT);
+ return (cur_pos == end_pos)? 1: 0;
+}
+
+
+
+class imBinSystemFileHandle: public imBinSystemFile
+{
+public:
+ virtual void Open(const char* pFileName);
+ virtual void New(const char* pFileName);
+ virtual void Close();
+};
+
+imBinFileBase* iBinSystemFileHandleNewFunc()
+{
+ return new imBinSystemFileHandle();
+}
+
+void imBinSystemFileHandle::Open(const char* pFileName)
+{
+ // the file was successfully opened already the client
+
+ HANDLE file_handle = (HANDLE)pFileName;
+ this->FileHandle = file_handle;
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 0;
+ this->Error = 0;
+}
+
+void imBinSystemFileHandle::New(const char* pFileName)
+{
+ // the file was successfully opened already the client
+
+ HANDLE file_handle = (HANDLE)pFileName;
+ this->FileHandle = file_handle;
+ InitByteOrder(imBinCPUByteOrder());
+ this->IsNew = 1;
+ this->Error = 0;
+}
+
+void imBinSystemFileHandle::Close()
+{
+ // does nothing, the client must close the file
+}
diff --git a/im/src/im_wmv.def b/im/src/im_wmv.def
new file mode 100755
index 0000000..1e017f3
--- /dev/null
+++ b/im/src/im_wmv.def
@@ -0,0 +1,2 @@
+EXPORTS
+ imFormatRegisterWMV \ No newline at end of file
diff --git a/im/src/im_wmv.mak b/im/src/im_wmv.mak
new file mode 100755
index 0000000..fef3c40
--- /dev/null
+++ b/im/src/im_wmv.mak
@@ -0,0 +1,23 @@
+PROJNAME = im
+LIBNAME = im_wmv
+OPT = YES
+
+SRC = im_format_wmv.cpp
+
+ifneq ($(findstring _64, $(TEC_UNAME)), )
+ WMFSDK = d:/lng/wmfsdk95
+ INCLUDES = $(WMFSDK)/include
+else
+# WMFSDK = d:/lng/wmfsdk11
+# EXTRAINCS = $(WMFSDK)/include
+ WMFSDK = d:/lng/wmfsdk9
+ INCLUDES = $(WMFSDK)/include
+endif
+
+DEFINES = _CRT_NON_CONFORMING_SWPRINTFS
+
+LDIR = $(WMFSDK)/lib
+LIBS = wmvcore
+
+USE_IM = Yes
+IM = ..
diff --git a/im/src/imlua3.def b/im/src/imlua3.def
new file mode 100755
index 0000000..d27384d
--- /dev/null
+++ b/im/src/imlua3.def
@@ -0,0 +1,2 @@
+EXPORTS
+ imlua_open \ No newline at end of file
diff --git a/im/src/imlua3.mak b/im/src/imlua3.mak
new file mode 100755
index 0000000..aac7b00
--- /dev/null
+++ b/im/src/imlua3.mak
@@ -0,0 +1,12 @@
+PROJNAME = im
+LIBNAME = imlua3
+OPT = YES
+
+SRC = im_lua3.c
+
+USE_LUA = Yes
+#Do NOT use USE_CD because we use no CD functions, only headers are used.
+INCLUDES = $(CD)/include
+
+USE_IM = Yes
+IM = ..
diff --git a/im/src/imlua5.mak b/im/src/imlua5.mak
new file mode 100755
index 0000000..554b701
--- /dev/null
+++ b/im/src/imlua5.mak
@@ -0,0 +1,18 @@
+PROJNAME = im
+LIBNAME = imlua51
+
+OPT = YES
+
+LOHDIR = lua5/loh
+SRC = lua5/imlua.c lua5/imlua_aux.c lua5/imlua_convert.c lua5/imlua_file.c lua5/imlua_image.c lua5/imlua_palette.c lua5/imlua_util.c
+DEF_FILE = lua5/imlua.def
+
+SRCLUA = lua5/im_image.lua lua5/im_convert.lua
+SRCLUADIR = lua5
+
+INCLUDES = lua5
+
+USE_IM = YES
+USE_LUA51 = YES
+NO_LUALINK = Yes
+IM = ..
diff --git a/im/src/imlua51.dep b/im/src/imlua51.dep
new file mode 100644
index 0000000..ff88e68
--- /dev/null
+++ b/im/src/imlua51.dep
@@ -0,0 +1,38 @@
+$(OBJDIR)/imlua.o: lua5/imlua.c ../include/im.h ../include/old_im.h \
+ ../include/im_lib.h ../include/im_image.h ../include/im_convert.h \
+ ../include/im_image.h ../../lua5.1/include/lua.h \
+ ../../lua5.1/include/luaconf.h ../../lua5.1/include/lauxlib.h \
+ ../../lua5.1/include/lua.h ../include/imlua.h lua5/imlua_aux.h \
+ lua5/imlua_image.h lua5/imlua_palette.h
+$(OBJDIR)/imlua_aux.o: lua5/imlua_aux.c ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_util.h ../../lua5.1/include/lua.h \
+ ../../lua5.1/include/luaconf.h ../../lua5.1/include/lauxlib.h \
+ ../../lua5.1/include/lua.h ../include/imlua.h lua5/imlua_aux.h \
+ lua5/imlua_image.h
+$(OBJDIR)/imlua_convert.o: lua5/imlua_convert.c ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_convert.h ../include/im_image.h \
+ ../../lua5.1/include/lua.h ../../lua5.1/include/luaconf.h \
+ ../../lua5.1/include/lauxlib.h ../../lua5.1/include/lua.h \
+ ../include/imlua.h lua5/imlua_image.h lua5/imlua_aux.h \
+ lua5/loh/im_convert_be64.loh
+$(OBJDIR)/imlua_file.o: lua5/imlua_file.c ../include/im.h ../include/old_im.h \
+ ../include/im_raw.h ../include/im_image.h ../include/im_util.h \
+ ../../lua5.1/include/lua.h ../../lua5.1/include/luaconf.h \
+ ../../lua5.1/include/lauxlib.h ../../lua5.1/include/lua.h \
+ ../include/imlua.h lua5/imlua_aux.h lua5/imlua_image.h \
+ lua5/imlua_palette.h
+$(OBJDIR)/imlua_image.o: lua5/imlua_image.c ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_util.h ../include/im_convert.h \
+ ../include/im_image.h ../../lua5.1/include/lua.h \
+ ../../lua5.1/include/luaconf.h ../../lua5.1/include/lauxlib.h \
+ ../../lua5.1/include/lua.h ../include/imlua.h lua5/imlua_image.h \
+ lua5/imlua_palette.h lua5/imlua_aux.h lua5/loh/im_image_be64.loh
+$(OBJDIR)/imlua_palette.o: lua5/imlua_palette.c ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_util.h ../include/im_palette.h \
+ ../../lua5.1/include/lua.h ../../lua5.1/include/luaconf.h \
+ ../../lua5.1/include/lauxlib.h ../../lua5.1/include/lua.h \
+ ../include/imlua.h lua5/imlua_aux.h lua5/imlua_palette.h
+$(OBJDIR)/imlua_util.o: lua5/imlua_util.c ../include/im.h ../include/old_im.h \
+ ../include/im_util.h ../include/im_image.h ../../lua5.1/include/lua.h \
+ ../../lua5.1/include/luaconf.h ../../lua5.1/include/lauxlib.h \
+ ../../lua5.1/include/lua.h ../include/imlua.h lua5/imlua_aux.h
diff --git a/im/src/imlua_capture5.mak b/im/src/imlua_capture5.mak
new file mode 100755
index 0000000..a4fe97c
--- /dev/null
+++ b/im/src/imlua_capture5.mak
@@ -0,0 +1,18 @@
+PROJNAME = im
+LIBNAME = imlua_capture51
+DEF_FILE = imlua_capture.def
+
+OPT = YES
+
+SRCDIR = lua5
+
+SRC = imlua_capture.c
+
+LIBS = im_capture
+
+INCLUDES = lua5
+
+USE_IMLUA = Yes
+USE_LUA51 = Yes
+NO_LUALINK = Yes
+IM = ..
diff --git a/im/src/imlua_process5.mak b/im/src/imlua_process5.mak
new file mode 100755
index 0000000..85415c4
--- /dev/null
+++ b/im/src/imlua_process5.mak
@@ -0,0 +1,19 @@
+PROJNAME = im
+LIBNAME = imlua_process51
+
+OPT = YES
+
+LOHDIR = lua5/loh
+SRC = lua5/imlua_process.c lua5/imlua_kernel.c
+DEF_FILE = lua5/imlua_process.def
+
+SRCLUA = lua5/im_process.lua
+SRCLUADIR = lua5
+
+LIBS = im_process
+INCLUDES = lua5
+
+USE_IMLUA = YES
+USE_LUA51 = YES
+NO_LUALINK = Yes
+IM = ..
diff --git a/im/src/imlua_process51.dep b/im/src/imlua_process51.dep
new file mode 100644
index 0000000..5f98a3b
--- /dev/null
+++ b/im/src/imlua_process51.dep
@@ -0,0 +1,17 @@
+$(OBJDIR)/imlua_process.o: lua5/imlua_process.c ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_process.h \
+ ../include/im_process_pon.h ../include/im_image.h \
+ ../include/im_process_loc.h ../include/im_process_glo.h \
+ ../include/im_process_ana.h ../include/im_util.h \
+ ../../lua5.1/include/lua.h ../../lua5.1/include/luaconf.h \
+ ../../lua5.1/include/lauxlib.h ../../lua5.1/include/lua.h \
+ ../include/imlua.h lua5/imlua_aux.h lua5/imlua_image.h \
+ lua5/loh/im_process_be64.loh
+$(OBJDIR)/imlua_kernel.o: lua5/imlua_kernel.c ../include/im.h ../include/old_im.h \
+ ../include/im_image.h ../include/im_process.h \
+ ../include/im_process_pon.h ../include/im_image.h \
+ ../include/im_process_loc.h ../include/im_process_glo.h \
+ ../include/im_process_ana.h ../include/im_util.h ../include/im_kernel.h \
+ ../../lua5.1/include/lua.h ../../lua5.1/include/luaconf.h \
+ ../../lua5.1/include/lauxlib.h ../../lua5.1/include/lua.h \
+ ../include/imlua.h lua5/imlua_aux.h lua5/imlua_image.h
diff --git a/im/src/imlua_wmv.mak b/im/src/imlua_wmv.mak
new file mode 100755
index 0000000..f487075
--- /dev/null
+++ b/im/src/imlua_wmv.mak
@@ -0,0 +1,17 @@
+PROJNAME = im
+LIBNAME = imlua_wmv51
+DEF_FILE = imlua_wmv.def
+
+OPT = YES
+
+SRCDIR = lua5
+
+SRC = imlua_wmv.c
+
+LIBS = im_wmv
+
+INCLUDES = lua5
+
+USE_IMLUA = Yes
+USE_LUA51 = Yes
+IM = ..
diff --git a/im/src/jas_binfile.c b/im/src/jas_binfile.c
new file mode 100755
index 0000000..487a2d3
--- /dev/null
+++ b/im/src/jas_binfile.c
@@ -0,0 +1,97 @@
+/** \file
+ * \brief libJasper I/O
+ * I/O uses imBinFile instead of libJasper original handlers.
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: jas_binfile.c,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include <stdlib.h>
+
+#include "jasper/jas_types.h"
+#include "jasper/jas_stream.h"
+#include "jasper/jas_malloc.h"
+#include "jasper/jas_math.h"
+
+#include "im_binfile.h"
+
+/* These were static in jas_stream.c */
+jas_stream_t *jas_stream_create(void);
+void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, int bufsize);
+
+static int file_read(jas_stream_obj_t *obj, char *buf, int cnt)
+{
+ imBinFile* file_bin = (imBinFile*)obj;
+ return imBinFileRead(file_bin, buf, cnt, 1);
+}
+
+static int file_write(jas_stream_obj_t *obj, char *buf, int cnt)
+{
+ imBinFile* file_bin = (imBinFile*)obj;
+ return imBinFileWrite(file_bin, buf, cnt, 1);
+}
+
+static long file_seek(jas_stream_obj_t *obj, long offset, int origin)
+{
+ imBinFile* file_bin = (imBinFile*)obj;
+ switch (origin)
+ {
+ case SEEK_SET:
+ imBinFileSeekTo(file_bin, offset);
+ break;
+ case SEEK_CUR:
+ imBinFileSeekOffset(file_bin, offset);
+ break;
+ case SEEK_END:
+ imBinFileSeekFrom(file_bin, offset);
+ break;
+ }
+
+ return imBinFileError(file_bin);
+}
+
+static int file_close(jas_stream_obj_t *obj)
+{
+ imBinFile* file_bin = (imBinFile*)obj;
+ imBinFileClose(file_bin);
+ return 0;
+}
+
+static jas_stream_ops_t jas_stream_fileops = {
+ file_read,
+ file_write,
+ file_seek,
+ file_close
+};
+
+jas_stream_t *jas_binfile_open(const char *file_name, int is_new)
+{
+ void* handle;
+ jas_stream_t *stream;
+
+ if (is_new)
+ handle = (void*)imBinFileNew(file_name);
+ else
+ handle = (void*)imBinFileOpen(file_name);
+
+ if (!handle)
+ return 0;
+
+ /* Allocate a stream object. */
+ stream = jas_stream_create();
+
+ if (is_new)
+ stream->openmode_ = JAS_STREAM_WRITE | JAS_STREAM_CREATE | JAS_STREAM_BINARY;
+ else
+ stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_BINARY;
+
+ /* Select the operations for a file stream object. */
+ stream->ops_ = &jas_stream_fileops;
+
+ stream->obj_ = handle;
+
+ /* By default, use full buffering for this type of stream. */
+ jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);
+
+ return stream;
+}
diff --git a/im/src/lua5/im_convert.lua b/im/src/lua5/im_convert.lua
new file mode 100755
index 0000000..231bdb5
--- /dev/null
+++ b/im/src/lua5/im_convert.lua
@@ -0,0 +1,18 @@
+
+function im.ConvertDataTypeNew(src_image, data_type, cpx2real, gamma, abssolute, cast_mode)
+ local dst_image = im.ImageCreateBased(src_image, nil, nil, nil, data_type)
+ return im.ConvertDataType(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode), dst_image
+end
+
+function im.ConvertColorSpaceNew(src_image, color_space, has_alpha)
+ local dst_image = im.ImageCreateBased(src_image, nil, nil, color_space)
+ if (has_alpha) then dst_image:AddAlpha() end
+ return im.ConvertColorSpace(src_image, dst_image), dst_image
+end
+
+function im.ConvertToBitmapNew(src_image, color_space, has_alpha, cpx2real, gamma, abssolute, cast_mode)
+ if (not color_space) then color_space = im.ColorModeToBitmap(src_image:ColorSpace()) end
+ local dst_image = im.ImageCreateBased(src_image, nil, nil, color_space)
+ if (has_alpha) then dst_image:AddAlpha() end
+ return im.ConvertToBitmap(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode), dst_image
+end
diff --git a/im/src/lua5/im_fftw.lua b/im/src/lua5/im_fftw.lua
new file mode 100755
index 0000000..7bae53e
--- /dev/null
+++ b/im/src/lua5/im_fftw.lua
@@ -0,0 +1,57 @@
+
+-------------------------------------------------------------------------------
+-- Creates a new function, with the name suffixed by "New". This new function
+-- creates a new image, based on a source image, and calls the previous function
+-- with this new image.
+-- We assume here that the functions returns only one parameter or none.
+
+local function OneSourceOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it receives two source
+-- images.
+
+local function TwoSourcesOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+
+ -- see if function is really defined
+ assert(func, string.format("undefined function `%s'", funcname))
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image1, src_image2, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image1, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image1, src_image2, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+
+TwoSourcesOneDest("ProcessCrossCorrelation")
+OneSourceOneDest("ProcessAutoCorrelation", nil, nil, nil, im.CFLOAT)
+OneSourceOneDest("ProcessFFT")
+OneSourceOneDest("ProcessIFFT")
diff --git a/im/src/lua5/im_image.lua b/im/src/lua5/im_image.lua
new file mode 100755
index 0000000..5eb9fd4
--- /dev/null
+++ b/im/src/lua5/im_image.lua
@@ -0,0 +1,24 @@
+-- If all parameteres, besides the image, are nil, this is equivalent to image:Clone.
+-- If any parameter is not nil, then the value is used instead of the one from the source image.
+-- If a parameter is a function, then the function is called, passing the source
+-- image as parameter, to obtain the substituion value.
+
+function im.ImageCreateBased(image, width, height, color_space, data_type)
+ -- default values are those of the source image
+ width = width or image:Width()
+ height = height or image:Height()
+ color_space = color_space or image:ColorSpace()
+ data_type = data_type or image:DataType()
+
+ -- callback to calculate parameters based on source image
+ if type(width) == "function" then width = width(image) end
+ if type(height) == "function" then height = height(image) end
+ if type(color_space) == "function" then color_space = color_space(image) end
+ if type(data_type) == "function" then data_type = data_type(image) end
+
+ -- create a new image
+ local new_image = im.ImageCreate(width, height, color_space, data_type)
+ image:CopyAttributes(new_image)
+ if (image:HasAlpha()) then new_image:AddAlpha() end
+ return new_image
+end
diff --git a/im/src/lua5/im_process.lua b/im/src/lua5/im_process.lua
new file mode 100755
index 0000000..d74c6b1
--- /dev/null
+++ b/im/src/lua5/im_process.lua
@@ -0,0 +1,329 @@
+
+-------------------------------------------------------------------------------
+-- Creates a new function, with the name suffixed by "New". This new function
+-- creates a new image, based on a source image, and calls the previous function
+-- with this new image.
+-- We assume here that the functions returns only one parameter or none.
+
+local function OneSourceOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it receives two source
+-- images.
+
+local function TwoSourcesOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+
+ -- see if function is really defined
+ assert(func, string.format("undefined function `%s'", funcname))
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image1, src_image2, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image1, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image1, src_image2, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it receives three source
+-- images.
+
+local function ThreeSourcesOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image1, src_image2, src_image3, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image1, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image1, src_image2, src_image3, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it creates two destiny
+-- images.
+
+local function OneSourceTwoDests (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image1 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+ local dst_image2 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image, dst_image1, dst_image2, unpack(arg))
+ if (ret) then
+ return ret, dst_image1, dst_image2
+ else
+ return dst_image1, dst_image2
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it creates three destiny
+-- images.
+
+local function OneSourceThreeDests (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image1 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+ local dst_image2 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+ local dst_image3 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image, dst_image1, dst_image2, dst_image3, unpack(arg))
+ if (ret) then
+ return ret, dst_image1, dst_image2, dst_image3
+ else
+ return dst_image1, dst_image2, dst_image3
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+
+local function hough_height(image)
+ local function sqr(x) return x*x end
+ local rmax = math.sqrt(sqr(image:Width()) + sqr(image:Height())) / 2
+ return 2*rmax+1
+end
+
+OneSourceOneDest("AnalyzeFindRegions", nil, nil, nil, im.USHORT)
+OneSourceOneDest("ProcessPerimeterLine")
+OneSourceOneDest("ProcessRemoveByArea")
+OneSourceOneDest("ProcessFillHoles")
+OneSourceOneDest("ProcessHoughLines", 180, hough_height, im.GRAY, im.INT)
+OneSourceOneDest("ProcessHoughLinesDraw")
+OneSourceOneDest("ProcessDistanceTransform", nil, nil, nil, im.FLOAT)
+OneSourceOneDest("ProcessRegionalMaximum", nil, nil, im.BINARY, nil)
+
+function im.ProcessReduceNew (src_image, width, height)
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ return im.ProcessReduce(src_image, dst_image), dst_image
+end
+
+function im.ProcessResizeNew (src_image, width, height)
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ return im.ProcessResize(src_image, dst_image), dst_image
+end
+
+OneSourceOneDest("ProcessReduceBy4", function (image) return image:Width() / 2 end,
+ function (image) return image:Height() / 2 end)
+
+function im.ProcessCropNew (src_image, xmin, xmax, ymin, ymax)
+ local width = xmax - xmin + 1
+ local height = ymax - ymin + 1
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ im.ProcessCrop(src_image, dst_image, xmin, ymin)
+ return dst_image
+end
+
+TwoSourcesOneDest("ProcessInsert")
+
+function im.ProcessAddMarginsNew (src_image, xmin, xmax, ymin, ymax)
+ local width = xmax - xmin + 1
+ local height = ymax - ymin + 1
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ im.ProcessAddMargins(src_image, dst_image, xmin, ymin)
+ return dst_image
+end
+
+function im.ProcessRotateNew (src_image, cos0, sin0, order)
+ local width, height = im.ProcessCalcRotateSize(src_image:Width(), src_image:Height(), cos0, sin0)
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ return im.ProcessRotate(src_image, dst_image, cos0, sin0, order), dst_image
+end
+
+OneSourceOneDest("ProcessRotateRef")
+OneSourceOneDest("ProcessRotate90", function (image) return image:Height() end, function (image) return image:Width() end)
+OneSourceOneDest("ProcessRotate180")
+OneSourceOneDest("ProcessMirror")
+OneSourceOneDest("ProcessFlip")
+OneSourceOneDest("ProcessRadial")
+OneSourceOneDest("ProcessGrayMorphConvolve")
+OneSourceOneDest("ProcessGrayMorphErode")
+OneSourceOneDest("ProcessGrayMorphDilate")
+OneSourceOneDest("ProcessGrayMorphOpen")
+OneSourceOneDest("ProcessGrayMorphClose")
+OneSourceOneDest("ProcessGrayMorphTopHat")
+OneSourceOneDest("ProcessGrayMorphWell")
+OneSourceOneDest("ProcessGrayMorphGradient")
+OneSourceOneDest("ProcessBinMorphConvolve")
+OneSourceOneDest("ProcessBinMorphErode")
+OneSourceOneDest("ProcessBinMorphDilate")
+OneSourceOneDest("ProcessBinMorphOpen")
+OneSourceOneDest("ProcessBinMorphClose")
+OneSourceOneDest("ProcessBinMorphOutline")
+OneSourceOneDest("ProcessBinMorphThin")
+OneSourceOneDest("ProcessMedianConvolve")
+OneSourceOneDest("ProcessRangeConvolve")
+OneSourceOneDest("ProcessRankClosestConvolve")
+OneSourceOneDest("ProcessRankMaxConvolve")
+OneSourceOneDest("ProcessRankMinConvolve")
+OneSourceOneDest("ProcessConvolve")
+OneSourceOneDest("ProcessConvolveSep")
+OneSourceOneDest("ProcessConvolveRep")
+OneSourceOneDest("ProcessConvolveDual")
+OneSourceOneDest("ProcessCompassConvolve")
+OneSourceOneDest("ProcessMeanConvolve")
+OneSourceOneDest("ProcessGaussianConvolve")
+OneSourceOneDest("ProcessBarlettConvolve")
+OneSourceTwoDests("ProcessInterlaceSplit", nil, function (image) if (image:Height()) then return image:Height() else return image:Height()/2 end end)
+
+function im.ProcessInterlaceSplitNew(src_image)
+ -- create destination image
+ local dst_height1 = src_image:Height()/2
+ if math.mod(src_image:Height(), 2) then
+ dst_height1 = dst_height1 + 1
+ end
+
+ local dst_image1 = im.ImageCreateBased(src_image, nil, dst_height1)
+ local dst_image2 = im.ImageCreateBased(src_image, nil, src_image:Height()/2)
+
+ -- call method, repassing all parameters
+ im.ProcessInterlaceSplit(src_image, dst_image1, dst_image2)
+ return dst_image1, dst_image2
+end
+
+local function int_datatype (image)
+ local data_type = image:DataType()
+ if data_type == im.BYTE or data_type == im.USHORT then
+ data_type = im.INT
+ end
+ return data_type
+end
+
+OneSourceOneDest("ProcessDiffOfGaussianConvolve", nil, nil, nil, int_datatype)
+OneSourceOneDest("ProcessLapOfGaussianConvolve", nil, nil, nil, int_datatype)
+OneSourceOneDest("ProcessSobelConvolve")
+OneSourceOneDest("ProcessSplineEdgeConvolve")
+OneSourceOneDest("ProcessPrewittConvolve")
+OneSourceOneDest("ProcessZeroCrossing")
+OneSourceOneDest("ProcessCanny")
+OneSourceOneDest("ProcessUnArithmeticOp")
+TwoSourcesOneDest("ProcessArithmeticOp")
+OneSourceOneDest("ProcessUnsharp")
+OneSourceOneDest("ProcessSharp")
+TwoSourcesOneDest("ProcessSharpKernel")
+
+function im.ProcessArithmeticConstOpNew (src_image, src_const, op)
+ local dst_image = im.ImageCreateBased(src_image)
+ im.ProcessArithmeticConstOp(src_image, src_const, dst_image, op)
+ return dst_image
+end
+
+TwoSourcesOneDest("ProcessBlendConst")
+ThreeSourcesOneDest("ProcessBlend")
+OneSourceTwoDests("ProcessSplitComplex")
+TwoSourcesOneDest("ProcessMergeComplex", nil, nil, nil, im.CFLOAT)
+
+function im.ProcessMultipleMeanNew (src_image_list, dst_image)
+ local dst_image = im.ImageCreateBased(src_image_list[1])
+ im.ProcessMultipleMean(src_image_list, dst_image)
+ return dst_image
+end
+
+function im.ProcessMultipleStdDevNew (src_image_list, mean_image)
+ local dst_image = im.ImageCreateBased(src_image_list[1])
+ im.ProcessMultipleStdDev(src_image_list, mean_image, dst_image)
+ return dst_image
+end
+
+TwoSourcesOneDest("ProcessAutoCovariance")
+OneSourceOneDest("ProcessMultiplyConj")
+OneSourceOneDest("ProcessQuantizeRGBUniform", nil, nil, im.MAP, nil)
+OneSourceOneDest("ProcessQuantizeGrayUniform")
+OneSourceOneDest("ProcessExpandHistogram")
+OneSourceOneDest("ProcessEqualizeHistogram")
+
+function im.ProcessSplitYChromaNew (src_image)
+ local y_image = im.ImageCreateBased(src_image, nil, nil, im.GRAY, im.BYTE)
+ local chroma_image = im.ImageCreateBased(src_image, nil, nil, im.RGB, im.BYTE)
+ im.ProcessSplitYChroma(src_image, y_image, chroma_image)
+ return y_image, chroma_image
+end
+
+OneSourceThreeDests("ProcessSplitHSI", nil, nil, im.GRAY, im.FLOAT)
+ThreeSourcesOneDest("ProcessMergeHSI", nil, nil, im.RGB, im.BYTE)
+
+function im.ProcessSplitComponentsNew (src_image)
+ local depth = src_image:Depth()
+ local dst_images = {}
+ for i = 1, depth do
+ table.insert(dst_images, im.ImageCreateBased(src_image, nil, nil, im.GRAY))
+ end
+ im.ProcessSplitComponents(src_image, dst_images)
+ return unpack(dst_images)
+end
+
+function im.ProcessMergeComponentsNew (src_image_list)
+ local dst_image = im.ImageCreateBased(src_image_list[1], nil, nil, im.RGB)
+ im.ProcessMergeComponents(src_image_list, dst_image)
+ return dst_image
+end
+
+OneSourceOneDest("ProcessNormalizeComponents", nil, nil, nil, im.FLOAT)
+OneSourceOneDest("ProcessReplaceColor")
+TwoSourcesOneDest("ProcessBitwiseOp")
+OneSourceOneDest("ProcessBitwiseNot")
+OneSourceOneDest("ProcessBitMask")
+OneSourceOneDest("ProcessBitPlane")
+OneSourceOneDest("ProcessToneGamut")
+OneSourceOneDest("ProcessUnNormalize", nil, nil, nil, im.BYTE)
+OneSourceOneDest("ProcessDirectConv", nil, nil, nil, im.BYTE)
+OneSourceOneDest("ProcessNegative")
+OneSourceOneDest("ProcessRangeContrastThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessLocalMaxThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessThreshold", nil, nil, im.BINARY, nil)
+TwoSourcesOneDest("ProcessThresholdByDiff")
+OneSourceOneDest("ProcessHysteresisThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessUniformErrThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessDifusionErrThreshold")
+OneSourceOneDest("ProcessPercentThreshold")
+OneSourceOneDest("ProcessOtsuThreshold")
+OneSourceOneDest("ProcessMinMaxThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessSliceThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessPixelate")
+OneSourceOneDest("ProcessPosterize")
+
diff --git a/im/src/lua5/imlua.c b/im/src/lua5/imlua.c
new file mode 100755
index 0000000..7e5c328
--- /dev/null
+++ b/im/src/lua5/imlua.c
@@ -0,0 +1,252 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua.c,v 1.2 2008/12/11 19:02:49 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_lib.h"
+#include "im_image.h"
+#include "im_convert.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+#include "imlua_palette.h"
+
+/*****************************************************************************\
+ im.Version()
+\*****************************************************************************/
+static int imluaVersion (lua_State *L)
+{
+ lua_pushstring(L, imVersion());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VersionDate()
+\*****************************************************************************/
+static int imluaVersionDate (lua_State *L)
+{
+ lua_pushstring(L, imVersionDate());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VersionNumber()
+\*****************************************************************************/
+static int imluaVersionNumber (lua_State *L)
+{
+ lua_pushnumber(L, imVersionNumber());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.FormatList()
+\*****************************************************************************/
+static int imluaFormatList (lua_State *L)
+{
+ int i, format_count;
+ char *format_list[50];
+
+ imFormatList(format_list, &format_count);
+
+ lua_newtable(L);
+ for (i = 0; i < format_count; i++)
+ {
+ lua_pushstring(L, format_list[i]);
+ lua_settable(L, -2);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.FormatInfo(format)
+\*****************************************************************************/
+static int imluaFormatInfo (lua_State *L)
+{
+ char desc[50];
+ char ext[50];
+ int can_sequence;
+ int error;
+
+ error = imFormatInfo(luaL_checkstring(L, 1), desc, ext, &can_sequence);
+
+ imlua_pusherror(L, error);
+ if (error)
+ return 1;
+
+ lua_pushstring(L, desc);
+ lua_pushstring(L, ext);
+ lua_pushboolean(L, can_sequence);
+
+ return 4;
+}
+
+/*****************************************************************************\
+ im.FormatCompressions(format)
+\*****************************************************************************/
+static int imluaFormatCompressions (lua_State *L)
+{
+ int i, comp_count;
+ int error;
+ char *comp[50];
+
+ int color_mode = luaL_optint(L, 2, -1);
+ int data_type = luaL_optint(L, 3, -1);
+
+ error = imFormatCompressions(luaL_checkstring(L, 1), comp, &comp_count, color_mode, data_type);
+
+ imlua_pusherror(L, error);
+ if (error)
+ return 1;
+
+ lua_newtable(L);
+ for (i = 0; i < comp_count; i++)
+ {
+ lua_pushstring(L, comp[i]);
+ lua_settable(L, -2);
+ }
+
+ return 2;
+}
+
+/*****************************************************************************\
+ im.FormatCanWriteImage(format, compression, color_mode, data_type)
+\*****************************************************************************/
+static int imluaFormatCanWriteImage (lua_State *L)
+{
+ const char *format = luaL_checkstring(L, 1);
+ const char *compression = luaL_checkstring(L, 2);
+ int color_mode = luaL_checkint(L, 3);
+ int data_type = luaL_checkint(L, 4);
+
+ lua_pushboolean(L, imFormatCanWriteImage(format, compression, color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ Constants
+\*****************************************************************************/
+static const imlua_constant im_constants[] = {
+
+ { "BYTE", IM_BYTE, NULL },
+ { "USHORT", IM_USHORT, NULL },
+ { "INT", IM_INT, NULL },
+ { "FLOAT", IM_FLOAT, NULL },
+ { "CFLOAT", IM_CFLOAT, NULL },
+
+ { "RGB", IM_RGB, NULL },
+ { "MAP", IM_MAP, NULL },
+ { "GRAY", IM_GRAY, NULL },
+ { "BINARY", IM_BINARY, NULL },
+ { "CMYK", IM_CMYK, NULL },
+ { "YCBCR", IM_YCBCR, NULL },
+ { "LAB", IM_LAB, NULL },
+ { "LUV", IM_LUV, NULL },
+ { "XYZ", IM_XYZ, NULL },
+
+ { "ALPHA", IM_ALPHA, NULL },
+ { "PACKED", IM_PACKED, NULL },
+ { "TOPDOWN", IM_TOPDOWN, NULL },
+
+ { "ERR_NONE", IM_ERR_NONE, NULL },
+ { "ERR_OPEN", IM_ERR_OPEN, NULL },
+ { "ERR_ACCESS", IM_ERR_ACCESS, NULL },
+ { "ERR_FORMAT", IM_ERR_FORMAT, NULL },
+ { "ERR_DATA", IM_ERR_DATA, NULL },
+ { "ERR_COMPRESS", IM_ERR_COMPRESS, NULL },
+ { "ERR_MEM", IM_ERR_MEM, NULL },
+ { "ERR_COUNTER", IM_ERR_COUNTER, NULL },
+
+ { "CPX_REAL", IM_CPX_REAL, NULL },
+ { "CPX_IMAG", IM_CPX_IMAG, NULL },
+ { "CPX_MAG", IM_CPX_MAG, NULL },
+ { "CPX_PHASE", IM_CPX_PHASE, NULL },
+
+ { "GAMMA_LINEAR", IM_GAMMA_LINEAR, NULL },
+ { "GAMMA_LOGLITE", IM_GAMMA_LOGLITE, NULL },
+ { "GAMMA_LOGHEAVY", IM_GAMMA_LOGHEAVY, NULL },
+ { "GAMMA_EXPLITE", IM_GAMMA_EXPLITE, NULL },
+ { "GAMMA_EXPHEAVY", IM_GAMMA_EXPHEAVY, NULL },
+
+ { "CAST_MINMAX", IM_CAST_MINMAX, NULL },
+ { "CAST_FIXED", IM_CAST_FIXED, NULL },
+ { "CAST_DIRECT", IM_CAST_DIRECT, NULL },
+
+ { "_AUTHOR", 0, IM_AUTHOR },
+ { "_COPYRIGHT", 0, IM_COPYRIGHT },
+ { "_VERSION_DATE", 0, IM_VERSION_DATE },
+ { "_DESCRIPTION", 0, IM_DESCRIPTION },
+ { "_NAME", 0, IM_NAME },
+
+ { NULL, -1, NULL },
+};
+
+void imlua_regconstants (lua_State *L, const imlua_constant *imconst)
+{
+ const imlua_constant *l = imconst;
+ for (; l->name; l++)
+ {
+ lua_pushstring(L, l->name);
+ if (l->str_value)
+ lua_pushstring(L, l->str_value);
+ else
+ lua_pushnumber(L, l->value);
+ lua_settable(L, -3);
+ }
+
+ lua_pushstring(L, "_VERSION");
+ lua_pushstring(L, imVersion());
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "_VERSION_NUMBER");
+ lua_pushnumber(L, imVersionNumber());
+ lua_settable(L, -3);
+}
+
+static const luaL_reg im_lib[] = {
+ {"Version", imluaVersion},
+ {"VersionDate", imluaVersionDate},
+ {"VersionNumber", imluaVersionNumber},
+
+ {"FormatList", imluaFormatList},
+ {"FormatInfo", imluaFormatInfo},
+ {"FormatCompressions", imluaFormatCompressions},
+ {"FormatCanWriteImage", imluaFormatCanWriteImage},
+
+ {NULL, NULL}
+};
+
+int imlua_open (lua_State *L)
+{
+ luaL_register(L, "im", im_lib); /* leave "im" table at the top of the stack */
+ imlua_regconstants(L, im_constants);
+
+ imlua_open_file(L);
+ imlua_open_image(L);
+ imlua_open_convert(L);
+ imlua_open_util(L);
+ imlua_open_palette(L);
+
+ return 1;
+}
+
+int luaopen_imlua(lua_State *L)
+{
+ return imlua_open(L);
+}
+
+int luaopen_imlua51(lua_State *L)
+{
+ return imlua_open(L);
+}
diff --git a/im/src/lua5/imlua.def b/im/src/lua5/imlua.def
new file mode 100755
index 0000000..259c822
--- /dev/null
+++ b/im/src/lua5/imlua.def
@@ -0,0 +1,24 @@
+EXPORTS
+ luaopen_imlua
+ luaopen_imlua51
+ imlua_open
+ imlua_checkimage
+ imlua_newarrayulong
+ imlua_newarrayint
+ imlua_newarrayfloat
+ imlua_checkdatatype
+ imlua_checkcolorspace
+ imlua_toarrayint
+ imlua_toarrayfloat
+ imlua_toarrayulong
+ imlua_getn
+ imlua_checktype
+ imlua_checkmask
+ imlua_regconstants
+ imlua_pushimage
+ imlua_matchcolor
+ imlua_matchsize
+ imlua_matchdatatype
+ imlua_matchcolorspace
+ imlua_match
+ \ No newline at end of file
diff --git a/im/src/lua5/imlua_aux.c b/im/src/lua5/imlua_aux.c
new file mode 100755
index 0000000..e472dca
--- /dev/null
+++ b/im/src/lua5/imlua_aux.c
@@ -0,0 +1,256 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_aux.c,v 1.2 2009/08/04 21:35:26 scuri Exp $
+ */
+
+#include <memory.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+/*****************************************************************************\
+\*****************************************************************************/
+int imlua_getn (lua_State *L, int index)
+{
+ int n;
+ lua_pushstring(L, "table");
+ lua_gettable(L, LUA_GLOBALSINDEX);
+ lua_pushstring(L, "getn");
+ lua_gettable(L, -2);
+ lua_pushvalue(L, index);
+ lua_call(L, 1, 1);
+ n = luaL_checkint(L, -1);
+ lua_pop(L, 2);
+ return n;
+}
+
+/*****************************************************************************\
+ Creates an int array.
+\*****************************************************************************/
+int imlua_newarrayint (lua_State *L, int *value, int count, int start)
+{
+ int i;
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ lua_pushnumber(L, value[i]);
+ lua_rawseti(L, -2, i+start);
+ }
+ return 1;
+}
+
+/*****************************************************************************\
+ Creates an unsigned long array.
+\*****************************************************************************/
+int imlua_newarrayulong (lua_State *L, unsigned long *value, int count, int start)
+{
+ int i;
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ lua_pushnumber(L, value[i]);
+ lua_rawseti(L, -2, i+start);
+ }
+ return 1;
+}
+
+/*****************************************************************************\
+ Creates a float array.
+\*****************************************************************************/
+int imlua_newarrayfloat (lua_State *L, float *value, int count, int start)
+{
+ int i;
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ lua_pushnumber(L, value[i]);
+ lua_rawseti(L, -2, i+start);
+ }
+ return 1;
+}
+
+/*****************************************************************************\
+ Retrieve an int array.
+\*****************************************************************************/
+int *imlua_toarrayint (lua_State *L, int index, int *count, int start)
+{
+ int i, n;
+ int *value = NULL;
+
+ if (lua_istable(L, index))
+ {
+ n = imlua_getn(L, index);
+ if (start == 0) n++;
+ if (count) *count = n;
+
+ value = (int*) malloc (sizeof(int) * n);
+ for (i = 0; i < n; i++)
+ {
+ lua_rawgeti(L, index, i+start);
+ value[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ return value;
+}
+
+/*****************************************************************************\
+ Retrieve an ulong array.
+\*****************************************************************************/
+unsigned long *imlua_toarrayulong (lua_State *L, int index, int *count, int start)
+{
+ int i, n;
+ unsigned long *value = NULL;
+
+ if (lua_istable(L, index))
+ {
+ n = imlua_getn(L, index);
+ if (start == 0) n++;
+ if (count) *count = n;
+
+ value = (unsigned long*) malloc (sizeof(unsigned long) * n);
+ for (i = 0; i < n; i++)
+ {
+ lua_rawgeti(L, index, i+start);
+ value[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ return value;
+}
+
+/*****************************************************************************\
+ Retrieve a float array.
+\*****************************************************************************/
+float *imlua_toarrayfloat (lua_State *L, int index, int *count, int start)
+{
+ int i, n;
+ float *value = NULL;
+
+ if (lua_istable(L, index))
+ {
+ n = imlua_getn(L, index);
+ if (start == 0) n++;
+ if (count) *count = n;
+
+ value = (float*) malloc (sizeof(float) * n);
+ for (i = 0; i < n; i++)
+ {
+ lua_rawgeti(L, index, i+start);
+ value[i] = (float) luaL_checknumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ return value;
+}
+
+
+/*****************************************************************************\
+ Creates a bit mask based on a string formatted as "11000110".
+\*****************************************************************************/
+unsigned char imlua_checkmask (lua_State *L, int index)
+{
+ int i;
+ unsigned char mask = 0;
+ const char *str = luaL_checkstring(L, index);
+ if (strlen(str) != 8)
+ luaL_argerror(L, index, "invalid mask, must have 8 elements");
+
+ for (i = 0; i < 8; i++)
+ {
+ char c = str[i];
+ if (c != '0' && c != '1')
+ luaL_argerror(L, index, "invalid mask, must have 0s or 1s only");
+
+ mask |= (c - '0') << (7 - i);
+ }
+
+ return mask;
+}
+
+/*****************************************************************************\
+ Checks data_type and color_space of an image. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_checktype (lua_State *L, int index, imImage *image, int color_space, int data_type)
+{
+ if (image->data_type != data_type)
+ {
+ char msg[100] = "image data type must be ";
+ strcat(msg, imDataTypeName(data_type));
+ luaL_argerror(L, index, msg);
+ }
+
+ if (image->color_space != color_space)
+ {
+ char msg[100] = "image color space must be ";
+ strcat(msg, imColorModeSpaceName(color_space));
+ luaL_argerror(L, index, msg);
+ }
+}
+
+/*****************************************************************************\
+ Checks color_space of an image. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_checkcolorspace (lua_State *L, int index, imImage *image, int color_space)
+{
+ if (image->color_space != color_space)
+ {
+ char msg[100] = "image color space must be ";
+ strcat(msg, imColorModeSpaceName(color_space));
+ luaL_argerror(L, index, msg);
+ }
+}
+
+/*****************************************************************************\
+ Checks a data_type of an image. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_checkdatatype (lua_State *L, int index, imImage *image, int data_type)
+{
+ if (image->data_type != data_type)
+ {
+ char msg[100] = "image data type must be ";
+ strcat(msg, imDataTypeName(data_type));
+ luaL_argerror(L, index, msg);
+ }
+}
+
+/*****************************************************************************\
+ Checks if the size of the two images are equal. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_matchsize(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchSize(image1, image2), "images must have the same size");
+}
+
+void imlua_matchcolor(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchColor(image1, image2), "images must have the same data type and color space");
+}
+
+void imlua_matchdatatype(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchDataType(image1, image2), "images must have the same size and data type");
+}
+
+void imlua_matchcolorspace(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchColorSpace(image1, image2), "images must have the same size and color space");
+}
+
+void imlua_match(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatch(image1, image2), "images must have the same size, data type and color space");
+}
diff --git a/im/src/lua5/imlua_aux.h b/im/src/lua5/imlua_aux.h
new file mode 100755
index 0000000..2dc4466
--- /dev/null
+++ b/im/src/lua5/imlua_aux.h
@@ -0,0 +1,82 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_aux.h,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#ifndef __IMLUA_AUX_H
+#define __IMLUA_AUX_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/********************************/
+/* exported from "imlua_aux.c". */
+/********************************/
+
+/* get table size */
+
+int imlua_getn(lua_State *L, int index);
+
+/* array */
+
+int imlua_newarrayint(lua_State *L, int *value, int count, int start);
+int imlua_newarrayulong(lua_State *L, unsigned long *value, int count, int start);
+int imlua_newarrayfloat(lua_State *L, float *value, int count, int start);
+
+int *imlua_toarrayint(lua_State *L, int index, int *count, int start);
+unsigned long *imlua_toarrayulong (lua_State *L, int index, int *count, int start);
+float *imlua_toarrayfloat(lua_State *L, int index, int *count, int start);
+
+/* other parameter checking */
+
+unsigned char imlua_checkmask(lua_State *L, int index);
+
+void imlua_checktype(lua_State *L, int index, imImage *image, int color_space, int data_type);
+void imlua_checkdatatype(lua_State *L, int index, imImage *image, int data_type);
+void imlua_checkcolorspace(lua_State *L, int index, imImage *image, int color_space);
+
+void imlua_matchsize(lua_State *L, imImage *image1, imImage *image2);
+void imlua_matchcolor(lua_State *L, imImage *image1, imImage *image2);
+void imlua_matchdatatype(lua_State *L, imImage *image1, imImage *image2);
+void imlua_matchcolorspace(lua_State *L, imImage *image1, imImage *image2);
+void imlua_match(lua_State *L, imImage *image1, imImage *image2);
+
+/* used only when comparing two images */
+#define imlua_matchcheck(L, cond, extramsg) if (!(cond)) \
+ luaL_error(L, extramsg)
+
+#define imlua_pusherror(L, _e) ((_e == IM_ERR_NONE)? lua_pushnil(L): lua_pushnumber(L, _e))
+
+
+/********************************/
+/* exported from "imlua.c". */
+/********************************/
+
+/* constant registration. */
+
+typedef struct _imlua_constant {
+ const char *name;
+ lua_Number value;
+ const char *str_value;
+} imlua_constant;
+
+void imlua_regconstants(lua_State *L, const imlua_constant *imconst);
+
+
+/********************************/
+/* private module open */
+/********************************/
+
+void imlua_open_convert(lua_State *L); /* imlua_convert.c */
+void imlua_open_util(lua_State *L); /* imlua_util.c */
+void imlua_open_file(lua_State *L); /* imlua_file.c */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/im/src/lua5/imlua_avi.c b/im/src/lua5/imlua_avi.c
new file mode 100755
index 0000000..f2cd7f4
--- /dev/null
+++ b/im/src/lua5/imlua_avi.c
@@ -0,0 +1,44 @@
+/** \file
+ * \brief AVI format Lua 5 Binding
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "im_format_avi.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+
+static int imlua_FormatRegisterAVI(lua_State *L)
+{
+ (void)L;
+ imFormatRegisterAVI();
+ return 0;
+}
+
+static const struct luaL_reg imlib[] = {
+ {"FormatRegisterAVI", imlua_FormatRegisterAVI},
+ {NULL, NULL},
+};
+
+
+static int imlua_avi_open (lua_State *L)
+{
+ imFormatRegisterAVI();
+ luaL_register(L, "im", imlib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_avi(lua_State* L)
+{
+ return imlua_avi_open(L);
+}
+
+int luaopen_imlua_avi51(lua_State* L)
+{
+ return imlua_avi_open(L);
+}
diff --git a/im/src/lua5/imlua_avi.def b/im/src/lua5/imlua_avi.def
new file mode 100755
index 0000000..3086a0d
--- /dev/null
+++ b/im/src/lua5/imlua_avi.def
@@ -0,0 +1,4 @@
+EXPORTS
+ luaopen_imlua_avi
+ luaopen_imlua_avi51
+ \ No newline at end of file
diff --git a/im/src/lua5/imlua_capture.c b/im/src/lua5/imlua_capture.c
new file mode 100755
index 0000000..59ec0fb
--- /dev/null
+++ b/im/src/lua5/imlua_capture.c
@@ -0,0 +1,443 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_capture.c,v 1.2 2009/08/12 04:09:17 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_capture.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+
+static imVideoCapture** imlua_rawcheckvideocapture (lua_State *L, int param)
+{
+ return (imVideoCapture**)luaL_checkudata(L, param, "imVideoCapture");
+}
+
+static imVideoCapture* imlua_checkvideocapture (lua_State *L, int param)
+{
+ imVideoCapture** vc_p = imlua_rawcheckvideocapture(L, param);
+
+ if (!(*vc_p))
+ luaL_argerror(L, param, "destroyed imVideoCapture");
+
+ return *vc_p;
+}
+
+static void imlua_pushvideocapture(lua_State *L, imVideoCapture* vc)
+{
+ if (!vc)
+ lua_pushnil(L);
+ else
+ {
+ imVideoCapture** vc_p = (imVideoCapture**) lua_newuserdata(L, sizeof(imVideoCapture*));
+ *vc_p = vc;
+ luaL_getmetatable(L, "imVideoCapture");
+ lua_setmetatable(L, -2);
+ }
+}
+
+/*****************************************************************************\
+ im.VideoCaptureDeviceCount()
+\*****************************************************************************/
+static int imluaVideoCaptureDeviceCount (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureDeviceCount());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VideoCaptureDeviceDesc(device)
+\*****************************************************************************/
+static int imluaVideoCaptureDeviceDesc (lua_State *L)
+{
+ lua_pushstring(L, imVideoCaptureDeviceDesc(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VideoCaptureDeviceDesc(device)
+\*****************************************************************************/
+static int imluaVideoCaptureReloadDevices (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureReloadDevices());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VideoCaptureCreate()
+\*****************************************************************************/
+static int imluaVideoCaptureCreate (lua_State *L)
+{
+ imlua_pushvideocapture(L, imVideoCaptureCreate());
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Connect([device])
+\*****************************************************************************/
+static int imluaVideoCaptureConnect (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int device = luaL_optint(L, 2, -1);
+ if (device == -1)
+ lua_pushnumber(L, imVideoCaptureConnect(vc, device));
+ else
+ lua_pushboolean(L, imVideoCaptureConnect(vc, device));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Disconnect()
+\*****************************************************************************/
+static int imluaVideoCaptureDisconnect (lua_State *L)
+{
+ imVideoCaptureDisconnect(imlua_checkvideocapture(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ vc:DialogCount()
+\*****************************************************************************/
+static int imluaVideoCaptureDialogCount (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureDialogCount(imlua_checkvideocapture(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:ShowDialog()
+\*****************************************************************************/
+static int imluaVideoCaptureShowDialog (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int dialog = luaL_checkint(L, 2);
+ void *parent = lua_touserdata(L, 3);
+
+ lua_pushboolean(L, imVideoCaptureShowDialog(vc, dialog, parent));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:DialogDesc()
+\*****************************************************************************/
+static int imluaVideoCaptureDialogDesc (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int dialog = luaL_checkint(L, 2);
+
+ lua_pushstring(L, imVideoCaptureDialogDesc(vc, dialog));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:FormatCount()
+\*****************************************************************************/
+static int imluaVideoCaptureFormatCount (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureFormatCount(imlua_checkvideocapture(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:GetFormat()
+\*****************************************************************************/
+static int imluaVideoCaptureGetFormat (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int format = luaL_checkint(L, 2);
+ int width, height;
+ char desc[10];
+
+ lua_pushboolean(L, imVideoCaptureGetFormat(vc, format, &width, &height, desc));
+ lua_pushnumber(L, width);
+ lua_pushnumber(L, height);
+ lua_pushstring(L, desc);
+
+ return 4;
+}
+
+/*****************************************************************************\
+ vc:GetImageSize()
+\*****************************************************************************/
+static int imluaVideoCaptureGetImageSize (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int width, height;
+
+ imVideoCaptureGetImageSize(vc, &width, &height);
+ lua_pushnumber(L, width);
+ lua_pushnumber(L, height);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ vc:SetImageSize()
+\*****************************************************************************/
+static int imluaVideoCaptureSetImageSize (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ lua_pushboolean(L, imVideoCaptureSetImageSize(vc, width, height));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:SetInOut()
+\*****************************************************************************/
+static int imluaVideoCaptureSetInOut(lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int input = luaL_checkint(L, 2);
+ int output = luaL_checkint(L, 3);
+ int cross = luaL_checkint(L, 4);
+
+ lua_pushboolean(L, imVideoCaptureSetInOut(vc, input, output, cross));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:SetFormat()
+\*****************************************************************************/
+static int imluaVideoCaptureSetFormat (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int format = luaL_optint(L, 2, -1);
+ if (format == -1)
+ lua_pushnumber(L, imVideoCaptureSetFormat(vc, format));
+ else
+ lua_pushboolean(L, imVideoCaptureSetFormat(vc, format));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:ResetAttribute(attrib, fauto)
+\*****************************************************************************/
+static int imluaVideoCaptureResetAttribute (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ int fauto = lua_toboolean(L, 3);
+
+ lua_pushboolean(L, imVideoCaptureResetAttribute(vc, attrib, fauto));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:SetAttribute(attrib, percent)
+\*****************************************************************************/
+static int imluaVideoCaptureSetAttribute (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ lua_pushboolean(L, imVideoCaptureSetAttribute(vc, attrib, percent));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:GetAttribute(attrib)
+\*****************************************************************************/
+static int imluaVideoCaptureGetAttribute (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ float percent;
+
+ lua_pushboolean(L, imVideoCaptureGetAttribute(vc, attrib, &percent));
+ lua_pushnumber(L, percent);
+ return 2;
+}
+
+/*****************************************************************************\
+ vc:GetAttributeList()
+\*****************************************************************************/
+static int imluaVideoCaptureGetAttributeList (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int num_attrib;
+ const char **attribs;
+ int i;
+
+ attribs = imVideoCaptureGetAttributeList(vc, &num_attrib);
+ lua_newtable(L);
+ for (i = 0; i < num_attrib; i++)
+ {
+ lua_pushstring(L, attribs[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Frame(image)
+\*****************************************************************************/
+static int imluaVideoCaptureFrame (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ imImage *image = imlua_checkimage(L, 2);
+ int timeout = luaL_checkint(L, 3);
+
+ if (!(image->color_space == IM_RGB || image->color_space == IM_GRAY))
+ luaL_argerror(L, 2, "image must be of RGB or Gray color spaces");
+ imlua_checkdatatype(L, 2, image, IM_BYTE);
+
+ lua_pushboolean(L, imVideoCaptureFrame(vc, image->data[0], image->color_space, timeout));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:OneFrame(image)
+\*****************************************************************************/
+static int imluaVideoCaptureOneFrame (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ imImage *image = imlua_checkimage(L, 2);
+
+ if (!(image->color_space == IM_RGB || image->color_space == IM_GRAY))
+ luaL_argerror(L, 2, "image must be of RGB or Gray color spaces");
+ imlua_checkdatatype(L, 2, image, IM_BYTE);
+
+ lua_pushboolean(L, imVideoCaptureOneFrame(vc, image->data[0], image->color_space));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Live(image)
+\*****************************************************************************/
+static int imluaVideoCaptureLive (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int live = luaL_optint(L, 2, -1);
+ if (live == -1)
+ lua_pushnumber(L, imVideoCaptureLive(vc, live));
+ else
+ lua_pushboolean(L, imVideoCaptureLive(vc, live));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Destroy()
+\*****************************************************************************/
+static int imluaVideoCaptureDestroy (lua_State *L)
+{
+ imVideoCapture **vc_p = imlua_rawcheckvideocapture(L, 1);
+ if (!(*vc_p))
+ luaL_argerror(L, 1, "destroyed imVideoCapture");
+
+ imVideoCaptureDestroy(*vc_p);
+ *vc_p = NULL; /* mark as destroyed */
+
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaVideoCapture_gc (lua_State *L)
+{
+ imVideoCapture **vc_p = (imVideoCapture **)lua_touserdata(L, 1);
+ if (*vc_p)
+ {
+ imVideoCaptureDestroy(*vc_p);
+ *vc_p = NULL; /* mark as destroyed */
+ }
+ return 0;
+}
+
+/*****************************************************************************\
+ tostring
+\*****************************************************************************/
+static int imluaVideoCapture_tostring (lua_State *L)
+{
+ imVideoCapture **vc_p = (imVideoCapture **)lua_touserdata(L, 1);
+ lua_pushfstring(L, "imVideoCapture (%p)%s", vc_p, (*vc_p)? "": "-destroyed");
+ return 1;
+}
+
+static const luaL_reg imcapture_lib[] = {
+ {"VideoCaptureDeviceCount", imluaVideoCaptureDeviceCount},
+ {"VideoCaptureDeviceDesc", imluaVideoCaptureDeviceDesc},
+ {"VideoCaptureReloadDevices", imluaVideoCaptureReloadDevices},
+ {"VideoCaptureCreate", imluaVideoCaptureCreate},
+ {"VideoCaptureDestroy", imluaVideoCaptureDestroy},
+ {NULL, NULL}
+};
+
+static const luaL_reg imcapture_metalib[] = {
+ {"Destroy", imluaVideoCaptureDestroy},
+ {"Connect", imluaVideoCaptureConnect},
+ {"Disconnect", imluaVideoCaptureDisconnect},
+ {"DialogCount", imluaVideoCaptureDialogCount},
+ {"ShowDialog", imluaVideoCaptureShowDialog},
+ {"DialogDesc", imluaVideoCaptureDialogDesc},
+ {"FormatCount", imluaVideoCaptureFormatCount},
+ {"GetFormat", imluaVideoCaptureGetFormat},
+ {"SetFormat", imluaVideoCaptureSetFormat},
+ {"GetImageSize", imluaVideoCaptureGetImageSize},
+ {"SetImageSize", imluaVideoCaptureSetImageSize},
+ {"SetInOut", imluaVideoCaptureSetInOut},
+ {"ResetAttribute", imluaVideoCaptureResetAttribute},
+ {"GetAttribute", imluaVideoCaptureGetAttribute},
+ {"SetAttribute", imluaVideoCaptureSetAttribute},
+ {"GetAttributeList", imluaVideoCaptureGetAttributeList},
+ {"OneFrame", imluaVideoCaptureOneFrame},
+ {"Frame", imluaVideoCaptureFrame},
+ {"Live", imluaVideoCaptureLive},
+
+ {"__gc", imluaVideoCapture_gc},
+ {"__tostring", imluaVideoCapture_tostring},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ /* Object Oriented Access */
+ luaL_newmetatable(L, "imVideoCapture"); /* create new metatable for imVideoCapture handle */
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, -2); /* push metatable */
+ lua_rawset(L, -3); /* metatable.__index = metatable */
+ luaL_register(L, NULL, imcapture_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+int imlua_open_capture(lua_State *L)
+{
+ createmeta(L);
+ luaL_register(L, "im", imcapture_lib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_capture(lua_State *L)
+{
+ return imlua_open_capture(L);
+}
+
+int luaopen_imlua_capture51(lua_State *L)
+{
+ return imlua_open_capture(L);
+}
+
diff --git a/im/src/lua5/imlua_capture.def b/im/src/lua5/imlua_capture.def
new file mode 100755
index 0000000..1b279cf
--- /dev/null
+++ b/im/src/lua5/imlua_capture.def
@@ -0,0 +1,5 @@
+EXPORTS
+ imlua_open_capture
+ luaopen_imlua_capture
+ luaopen_imlua_capture51
+ \ No newline at end of file
diff --git a/im/src/lua5/imlua_convert.c b/im/src/lua5/imlua_convert.c
new file mode 100755
index 0000000..c2c56d9
--- /dev/null
+++ b/im/src/lua5/imlua_convert.c
@@ -0,0 +1,96 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_convert.c,v 1.3 2009/08/18 02:23:33 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_image.h"
+#include "im_convert.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_image.h"
+#include "imlua_aux.h"
+
+/*****************************************************************************\
+ im.ConvertDataType(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode)
+\*****************************************************************************/
+static int imluaConvertDataType (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int cpx2real = luaL_checkint(L, 3);
+ float gamma = (float) luaL_checknumber(L, 4);
+ int abssolute = lua_toboolean(L, 5);
+ int cast_mode = luaL_checkint(L, 6);
+
+ imlua_matchcolorspace(L, src_image, dst_image);
+ imlua_pusherror(L, imConvertDataType(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ConvertColorSpace(src_image, dst_image)
+\*****************************************************************************/
+static int imluaConvertColorSpace (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchdatatype(L, src_image, dst_image);
+ imlua_pusherror(L, imConvertColorSpace(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ConvertToBitmap(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode)
+\*****************************************************************************/
+static int imluaConvertToBitmap (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int cpx2real = luaL_checkint(L, 3);
+ float gamma = (float) luaL_checknumber(L, 4);
+ int abssolute = lua_toboolean(L, 5);
+ int cast_mode = luaL_checkint(L, 6);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_matchcheck(L, imImageIsBitmap(dst_image), "image must be a bitmap");
+
+ imlua_pusherror(L, imConvertToBitmap(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode));
+ return 1;
+}
+
+static const luaL_reg imconvert_lib[] = {
+ {"ConvertDataType", imluaConvertDataType},
+ {"ConvertColorSpace", imluaConvertColorSpace},
+ {"ConvertToBitmap", imluaConvertToBitmap},
+ {NULL, NULL}
+};
+
+void imlua_open_convert (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ luaL_register(L, NULL, imconvert_lib);
+#ifdef TEC_BIGENDIAN
+#ifdef TEC_64
+#include "loh/im_convert_be64.loh"
+#else
+#include "loh/im_convert_be32.loh"
+#endif
+#else
+#ifdef TEC_64
+#ifdef WIN64
+#include "loh/im_convert_le64w.loh"
+#else
+#include "loh/im_convert_le64.loh"
+#endif
+#else
+#include "loh/im_convert.loh"
+#endif
+#endif
+}
diff --git a/im/src/lua5/imlua_fftw.c b/im/src/lua5/imlua_fftw.c
new file mode 100755
index 0000000..c8ad3df
--- /dev/null
+++ b/im/src/lua5/imlua_fftw.c
@@ -0,0 +1,162 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_fftw.c,v 1.2 2008/11/26 17:25:51 scuri Exp $
+ */
+
+#include <memory.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_process.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+/*****************************************************************************\
+ Domain Transform Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessFFT(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessFFT (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_CFLOAT);
+
+ imProcessFFT(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessIFFT(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessIFFT (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+ imlua_checkdatatype(L, 2, dst_image, IM_CFLOAT);
+
+ imProcessIFFT(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessFFTRaw(src_image, inverse, center, normalize)
+\*****************************************************************************/
+static int imluaProcessFFTraw (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ int inverse = luaL_checkint(L, 2);
+ int center = luaL_checkint(L, 3);
+ int normalize = luaL_checkint(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+
+ imProcessFFTraw(src_image, inverse, center, normalize);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSwapQuadrants(src_image, inverse, center, normalize)
+\*****************************************************************************/
+static int imluaProcessSwapQuadrants (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ int center2origin = luaL_checkint(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+
+ imProcessSwapQuadrants(src_image, center2origin);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessCrossCorrelation(image1, image2, dst_image)
+\*****************************************************************************/
+static int imluaProcessCrossCorrelation (lua_State *L)
+{
+ imImage* image1 = imlua_checkimage(L, 1);
+ imImage* image2 = imlua_checkimage(L, 2);
+ imImage* dst_image = imlua_checkimage(L, 3);
+
+ imlua_matchsize(L, image1, dst_image);
+ imlua_matchsize(L, image2, dst_image);
+ imlua_checkdatatype(L, 3, dst_image, IM_CFLOAT);
+
+ imProcessCrossCorrelation(image1, image2, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessAutoCorrelation(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessAutoCorrelation (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_CFLOAT);
+
+ imProcessAutoCorrelation(src_image, dst_image);
+ return 0;
+}
+
+static const luaL_reg imfftw_lib[] = {
+ {"ProcessFFT", imluaProcessFFT},
+ {"ProcessIFFT", imluaProcessIFFT},
+ {"ProcessFFTraw", imluaProcessFFTraw},
+ {"ProcessSwapQuadrants", imluaProcessSwapQuadrants},
+ {"ProcessCrossCorrelation", imluaProcessCrossCorrelation},
+ {"ProcessAutoCorrelation", imluaProcessAutoCorrelation},
+
+ {NULL, NULL}
+};
+
+int imlua_open_fftw (lua_State *L)
+{
+ luaL_register(L, "im", imfftw_lib); /* leave "im" table at the top of the stack */
+#ifdef TEC_BIGENDIAN
+#ifdef TEC_64
+#include "loh/im_fftw_be64.loh"
+#else
+#include "loh/im_fftw_be32.loh"
+#endif
+#else
+#ifdef TEC_64
+#ifdef WIN64
+#include "loh/im_fftw_le64w.loh"
+#else
+#include "loh/im_fftw_le64.loh"
+#endif
+#else
+#include "loh/im_fftw.loh"
+#endif
+#endif
+ return 1;
+}
+
+int luaopen_imlua_fftw(lua_State *L)
+{
+ return imlua_open_fftw(L);
+}
+
+int luaopen_imlua_fftw51(lua_State *L)
+{
+ return imlua_open_fftw(L);
+}
diff --git a/im/src/lua5/imlua_fftw.def b/im/src/lua5/imlua_fftw.def
new file mode 100755
index 0000000..216c967
--- /dev/null
+++ b/im/src/lua5/imlua_fftw.def
@@ -0,0 +1,4 @@
+EXPORTS
+ imlua_open_fftw
+ luaopen_imlua_fftw
+ luaopen_imlua_fftw51 \ No newline at end of file
diff --git a/im/src/lua5/imlua_file.c b/im/src/lua5/imlua_file.c
new file mode 100755
index 0000000..066dd76
--- /dev/null
+++ b/im/src/lua5/imlua_file.c
@@ -0,0 +1,661 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_file.c,v 1.2 2009/08/04 21:35:26 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_raw.h"
+#include "im_image.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+#include "imlua_palette.h"
+
+
+
+static imFile** imlua_rawcheckfile(lua_State *L, int param)
+{
+ return (imFile**)luaL_checkudata(L, param, "imFile");
+}
+
+static imFile* imlua_checkfile (lua_State *L, int param)
+{
+ imFile** ifile_p = imlua_rawcheckfile(L, param);
+
+ if (!(*ifile_p))
+ luaL_argerror(L, param, "closed imFile");
+
+ return *ifile_p;
+}
+
+static int imlua_pushifileerror(lua_State *L, imFile* ifile, int error)
+{
+ if (error)
+ {
+ lua_pushnil(L);
+ imlua_pusherror(L, error);
+ return 2;
+ }
+ else
+ {
+ imFile** ifile_p = (imFile**) lua_newuserdata(L, sizeof(imFile*));
+ *ifile_p = ifile;
+ luaL_getmetatable(L, "imFile");
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+}
+
+
+/*****************************************************************************\
+ im.FileOpen(filename)
+\*****************************************************************************/
+static int imluaFileOpen (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int error;
+ imFile *ifile = imFileOpen(filename, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileOpenAs(filename)
+\*****************************************************************************/
+static int imluaFileOpenAs (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ const char *format = luaL_checkstring(L, 2);
+ int error;
+ imFile *ifile = imFileOpenAs(filename, format, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileOpenRaw(filename)
+\*****************************************************************************/
+static int imluaFileOpenRaw (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int error;
+ imFile *ifile = imFileOpenRaw(filename, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileNew(filename, format)
+\*****************************************************************************/
+static int imluaFileNew (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ const char *format = luaL_checkstring(L, 2);
+ int error;
+
+ imFile *ifile = imFileNew(filename, format, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileNewRaw(filename)
+\*****************************************************************************/
+static int imluaFileNewRaw (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int error;
+ imFile *ifile = imFileNewRaw(filename, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ file:Handle()
+\*****************************************************************************/
+static int imluaFileHandle (lua_State *L)
+{
+ lua_pushlightuserdata(L, imFileHandle(imlua_checkfile(L, 1), luaL_checkint(L, 2)));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:LoadImage()
+\*****************************************************************************/
+static int imluaFileLoadImage (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileLoadImage(ifile, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ file:LoadImageFrame()
+\*****************************************************************************/
+static int imluaFileLoadImageFrame (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_checkint(L, 2);
+ imImage *image = imlua_checkimage(L, 3);
+ int error;
+
+ imFileLoadImageFrame(ifile, index, image, &error);
+ imlua_pusherror(L, error);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ file:LoadImageRegion()
+\*****************************************************************************/
+static int imluaFileLoadImageRegion (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_checkint(L, 2);
+ int bitmap = luaL_checkint(L, 3);
+ int xmin = luaL_checkint(L, 4);
+ int xmax = luaL_checkint(L, 5);
+ int ymin = luaL_checkint(L, 6);
+ int ymax = luaL_checkint(L, 7);
+ int width = luaL_checkint(L, 8);
+ int height = luaL_checkint(L, 9);
+ int error;
+ imImage *image = imFileLoadImageRegion(ifile, index, bitmap, &error, xmin, xmax, ymin, ymax, width, height);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ file:LoadBitmap()
+\*****************************************************************************/
+static int imluaFileLoadBitmap (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileLoadBitmap(ifile, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ file:LoadBitmapFrame()
+\*****************************************************************************/
+static int imluaFileLoadBitmapFrame (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_checkint(L, 2);
+ imImage *image = imlua_checkimage(L, 3);
+ int error;
+
+ imFileLoadBitmapFrame(ifile, index, image, &error);
+ imlua_pusherror(L, error);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ file:SaveImage()
+\*****************************************************************************/
+static int imluaFileSaveImage (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ imImage *image = imlua_checkimage(L, 2);
+
+ imlua_pusherror(L, imFileSaveImage(ifile, image));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:GetInfo()
+\*****************************************************************************/
+static int imluaFileGetInfo (lua_State *L)
+{
+ int image_count;
+ char format[10];
+ char compression[20];
+
+ imFile *ifile = imlua_checkfile(L, 1);
+
+ imFileGetInfo(ifile, format, compression, &image_count);
+
+ lua_pushstring(L, format);
+ lua_pushstring(L, compression);
+ lua_pushnumber(L, image_count);
+
+ return 3;
+}
+
+/*****************************************************************************\
+ file:SetInfo()
+\*****************************************************************************/
+static int imluaFileSetInfo (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ const char *compression = luaL_checkstring(L, 2);
+
+ imFileSetInfo(ifile, compression);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ file:SetAttribute(attrib, data_type, data)
+\*****************************************************************************/
+static int imluaFileSetAttribute (lua_State *L)
+{
+ int i, count = 0;
+ void *data = NULL;
+
+ imFile *ifile = imlua_checkfile(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ int data_type = luaL_checkint(L, 3);
+
+ if (!lua_isnil(L, 4))
+ {
+ if (lua_isstring(L, 4) && data_type != IM_BYTE)
+ luaL_argerror(L, 4, "if value is a string, then data type must be byte");
+ else
+ {
+ luaL_checktype(L, 4, LUA_TTABLE);
+ count = imlua_getn(L, 4);
+ data = malloc(imDataTypeSize(data_type) * count);
+ }
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (lua_isstring(L, 4))
+ {
+ const char* str = lua_tostring(L, 4);
+ count = strlen(str)+1;
+ data = malloc(imDataTypeSize(data_type) * count);
+ memcpy(data, str, count);
+ }
+ else
+ {
+ imbyte *d = (imbyte*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = (imbyte) luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *d = (imushort*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = (imushort) luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *d = (int*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *d = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = (float) luaL_checknumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ int two;
+ float *value = imlua_toarrayfloat(L, -1, &two, 1);
+ if (two != 2)
+ {
+ free(value);
+ luaL_argerror(L, 4, "invalid value");
+ }
+
+ data_float[i] = value[0];
+ data_float[i+1] = value[1];
+ free(value);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+ }
+ }
+
+ imFileSetAttribute(ifile, attrib, data_type, count, data);
+ return 0;
+}
+
+/*****************************************************************************\
+ file:GetAttribute(attrib)
+\*****************************************************************************/
+static int imluaFileGetAttribute (lua_State *L)
+{
+ int data_type;
+ int i, count;
+ const void *data;
+ int as_string = 0;
+
+ imFile *ifile = imlua_checkfile(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+
+ data = imFileGetAttribute(ifile, attrib, &data_type, &count);
+ if (!data)
+ {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ if (data_type == IM_BYTE && lua_isboolean(L, 3))
+ as_string = lua_toboolean(L, 3);
+
+ if (!as_string)
+ lua_newtable(L);
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (as_string)
+ {
+ lua_pushstring(L, (const char*)data);
+ }
+ else
+ {
+ imbyte *data_byte = (imbyte*) data;
+ for (i = 0; i < count; i++, data_byte++)
+ {
+ lua_pushnumber(L, *data_byte);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *data_ushort = (imushort*) data;
+ for (i = 0; i < count; i++, data_ushort += 2)
+ {
+ lua_pushnumber(L, *data_ushort);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *data_int = (int*) data;
+ for (i = 0; i < count; i++, data_int++)
+ {
+ lua_pushnumber(L, *data_int);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float++)
+ {
+ lua_pushnumber(L, *data_float);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float += 2)
+ {
+ imlua_newarrayfloat(L, data_float, 2, 1);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+ }
+
+ lua_pushnumber(L, data_type);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ file:GetAttributeList()
+\*****************************************************************************/
+static int imluaFileGetAttributeList (lua_State *L)
+{
+ int i, attrib_count;
+ char **attrib;
+
+ imFile* ifile = imlua_checkfile(L, 1);
+
+ imFileGetAttributeList(ifile, NULL, &attrib_count);
+
+ attrib = (char**) malloc(attrib_count * sizeof(char*));
+
+ imFileGetAttributeList(ifile, attrib, &attrib_count);
+
+ lua_newtable(L);
+ for (i = 0; i < attrib_count; i++)
+ {
+ lua_pushstring(L, attrib[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ file:GetPalette()
+\*****************************************************************************/
+static int imluaFileGetPalette (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ long* color = malloc(sizeof(long) * 256);
+ int count;
+ imFileGetPalette(ifile, color, &count);
+ imlua_pushpalette(L, color, count);
+ return 1;
+}
+
+/*****************************************************************************\
+ file:SetPalette(pal)
+\*****************************************************************************/
+static int imluaFileSetPalette (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ imluaPalette *pal = imlua_checkpalette(L, 2);
+ imFileSetPalette(ifile, pal->color, pal->count);
+ return 0;
+}
+
+/*****************************************************************************\
+ file:ReadImageInfo()
+\*****************************************************************************/
+static int imluaFileReadImageInfo (lua_State *L)
+{
+ int width, height;
+ int file_color_mode, file_data_type;
+ int error;
+
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_optint(L, 2, 0);
+
+ error = imFileReadImageInfo(ifile, index, &width, &height, &file_color_mode, &file_data_type);
+
+ imlua_pusherror(L, error);
+ if (error)
+ return 1;
+
+ lua_pushnumber(L, width);
+ lua_pushnumber(L, height);
+ lua_pushnumber(L, file_color_mode);
+ lua_pushnumber(L, file_data_type);
+ return 5;
+}
+
+/*****************************************************************************\
+ file:WriteImageInfo(width, height, user_color_mode, user_data_type)
+\*****************************************************************************/
+static int imluaFileWriteImageInfo (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+ int user_color_mode = luaL_checkint(L, 4);
+ int user_data_type = luaL_checkint(L, 5);
+
+ imlua_pusherror(L, imFileWriteImageInfo(ifile, width, height, user_color_mode, user_data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:ReadImageData(data)
+\*****************************************************************************/
+static int imluaFileReadImageData (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ void* data = lua_touserdata(L, 2);
+ int convert2bitmap = lua_toboolean(L, 3);
+ int color_mode_flags = luaL_checkint(L, 4);
+ imlua_pusherror(L, imFileReadImageData(ifile, data, convert2bitmap, color_mode_flags));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:WriteImageData(data)
+\*****************************************************************************/
+static int imluaFileWriteImageData (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ void* data = lua_touserdata(L, 2);
+ imlua_pusherror(L, imFileWriteImageData(ifile, data));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:Close()
+\*****************************************************************************/
+static int imluaFileClose (lua_State *L)
+{
+ imFile** ifile_p = imlua_rawcheckfile(L, 1);
+ if (!(*ifile_p))
+ luaL_argerror(L, 1, "closed imFile");
+
+ imFileClose(*ifile_p);
+ *ifile_p = NULL; /* mark as closed */
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaFile_gc (lua_State *L)
+{
+ imFile **ifile_p = (imFile **)lua_touserdata(L, 1);
+ if (ifile_p && *ifile_p)
+ {
+ imFileClose(*ifile_p);
+ *ifile_p = NULL; /* mark as closed */
+ }
+ return 0;
+}
+
+/*****************************************************************************\
+ tostring
+\*****************************************************************************/
+static int imluaFile_tostring (lua_State *L)
+{
+ imFile **ifile_p = (imFile **)lua_touserdata(L, 1);
+ lua_pushfstring(L, "imFile(%p)%s", ifile_p, (*ifile_p)? "": "-closed");
+ return 1;
+}
+
+/*****************************************************************************\
+\*****************************************************************************/
+static const luaL_reg imfile_lib[] = {
+ {"FileOpen", imluaFileOpen},
+ {"FileOpenAs", imluaFileOpenAs},
+ {"FileOpenRaw", imluaFileOpenRaw},
+ {"FileNew", imluaFileNew},
+ {"FileNewRaw", imluaFileNewRaw},
+ {"FileClose", imluaFileClose},
+ {NULL, NULL}
+};
+
+static const luaL_reg imfile_metalib[] = {
+ {"Handle", imluaFileHandle},
+ {"Close", imluaFileClose},
+ {"LoadImage", imluaFileLoadImage},
+ {"LoadImageFrame", imluaFileLoadImageFrame},
+ {"LoadImageRegion", imluaFileLoadImageRegion},
+ {"LoadBitmap", imluaFileLoadBitmap},
+ {"LoadBitmapFrame", imluaFileLoadBitmapFrame},
+ {"SaveImage", imluaFileSaveImage},
+ {"GetInfo", imluaFileGetInfo},
+ {"SetInfo", imluaFileSetInfo},
+ {"SetAttribute", imluaFileSetAttribute},
+ {"GetAttribute", imluaFileGetAttribute},
+ {"GetAttributeList", imluaFileGetAttributeList},
+ {"GetPalette", imluaFileGetPalette},
+ {"SetPalette", imluaFileSetPalette},
+ {"ReadImageInfo", imluaFileReadImageInfo},
+ {"WriteImageInfo", imluaFileWriteImageInfo},
+ {"ReadImageData", imluaFileReadImageData},
+ {"WriteImageData", imluaFileWriteImageData},
+
+ {"__gc", imluaFile_gc},
+ {"__tostring", imluaFile_tostring},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ /* Object Oriented Access */
+ luaL_newmetatable(L, "imFile"); /* create new metatable for imFile handles */
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, -2); /* push metatable */
+ lua_rawset(L, -3); /* metatable.__index = metatable */
+ luaL_register(L, NULL, imfile_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+void imlua_open_file (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ createmeta(L);
+ luaL_register(L, NULL, imfile_lib);
+}
diff --git a/im/src/lua5/imlua_image.c b/im/src/lua5/imlua_image.c
new file mode 100755
index 0000000..40b1e9c
--- /dev/null
+++ b/im/src/lua5/imlua_image.c
@@ -0,0 +1,1083 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_image.c,v 1.5 2009/09/25 18:40:31 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+#include "im_convert.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_image.h"
+#include "imlua_palette.h"
+#include "imlua_aux.h"
+
+
+static imImage** imlua_rawcheckimage(lua_State *L, int param)
+{
+ return (imImage**) luaL_checkudata(L, param, "imImage");
+}
+
+imImage* imlua_checkimage(lua_State *L, int param)
+{
+ imImage** image_p = imlua_rawcheckimage(L, param);
+
+ if (!(*image_p))
+ luaL_argerror(L, param, "destroyed imImage");
+
+ return *image_p;
+}
+
+int imlua_pushimageerror(lua_State *L, imImage* image, int error)
+{
+ if (error)
+ {
+ lua_pushnil(L);
+ imlua_pusherror(L, error);
+ return 2;
+ }
+ else
+ {
+ imlua_pushimage(L, image);
+ return 1;
+ }
+}
+
+void imlua_pushimage(lua_State *L, imImage* image)
+{
+ if (!image)
+ lua_pushnil(L);
+ else
+ {
+ imImage **image_p = (imImage**) lua_newuserdata(L, sizeof(imImage*));
+ *image_p = image;
+ luaL_getmetatable(L, "imImage");
+ lua_setmetatable(L, -2);
+ }
+}
+
+/*****************************************************************************\
+ image channel, for indexing
+\*****************************************************************************/
+static imluaImageChannel *imlua_newimagechannel (lua_State *L, imImage *image, int channel)
+{
+ imluaImageChannel* imagechannel = (imluaImageChannel*) lua_newuserdata(L, sizeof(imluaImageChannel));
+ imagechannel->image = image;
+ imagechannel->channel = channel;
+ luaL_getmetatable(L, "imImageChannel");
+ lua_setmetatable(L, -2);
+ return imagechannel;
+}
+
+static imluaImageChannel* imlua_checkimagechannel (lua_State *L, int param)
+{
+ return (imluaImageChannel*) luaL_checkudata(L, param, "imImageChannel");
+}
+
+/*****************************************************************************\
+ image row, for indexing
+\*****************************************************************************/
+static imluaImageRow *imlua_newimagerow (lua_State *L, imImage *image, int channel, int row)
+{
+ imluaImageRow* imagerow = (imluaImageRow*) lua_newuserdata(L, sizeof(imluaImageRow));
+ imagerow->image = image;
+ imagerow->channel = channel;
+ imagerow->row = row;
+ luaL_getmetatable(L, "imImageChannelRow");
+ lua_setmetatable(L, -2);
+ return imagerow;
+}
+
+static imluaImageRow* imlua_checkimagerow (lua_State *L, int param)
+{
+ return (imluaImageRow*) luaL_checkudata(L, param, "imImageChannelRow");
+}
+
+/*****************************************************************************\
+ im.ImageCreate(width, height, color_space, data_type)
+\*****************************************************************************/
+static int imluaImageCreate (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int height = luaL_checkint(L, 2);
+ int color_space = luaL_checkint(L, 3);
+ int data_type = luaL_checkint(L, 4);
+
+ imImage *image = imImageCreate(width, height, color_space, data_type);
+ imlua_pushimage(L, image);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:AddAlpha()
+\*****************************************************************************/
+static int imluaImageAddAlpha (lua_State *L)
+{
+ imImageAddAlpha(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Reshape()
+\*****************************************************************************/
+static int imluaImageReshape (lua_State *L)
+{
+ imImage* im = imlua_checkimage(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ imImageReshape(im, width, height);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Copy()
+\*****************************************************************************/
+static int imluaImageCopy (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+ imImageCopy(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:CopyData()
+\*****************************************************************************/
+static int imluaImageCopyData (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+ imImageCopyData(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Duplicate()
+\*****************************************************************************/
+static int imluaImageDuplicate (lua_State *L)
+{
+ imImage* image = imlua_checkimage(L, 1);
+ imImage *new_image = imImageDuplicate(image);
+ imlua_pushimage(L, new_image);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Clone()
+\*****************************************************************************/
+static int imluaImageClone (lua_State *L)
+{
+ imImage* image = imlua_checkimage(L, 1);
+ imImage *new_image = imImageClone(image);
+ imlua_pushimage(L, new_image);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:SetAttribute(attrib, data_type, count, data)
+\*****************************************************************************/
+static int imluaImageSetAttribute (lua_State *L)
+{
+ int i, count = 0;
+ void *data = NULL;
+
+ imImage* image = imlua_checkimage(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ int data_type = luaL_checkint(L, 3);
+
+ if (!lua_isnil(L, 4))
+ {
+ if (lua_isstring(L, 4) && data_type != IM_BYTE)
+ luaL_argerror(L, 4, "if value is string, then data type must be byte");
+ else
+ {
+ luaL_checktype(L, 4, LUA_TTABLE);
+ count = imlua_getn(L, 4);
+ data = malloc(imDataTypeSize(data_type) * count);
+ }
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (lua_isstring(L, 4))
+ {
+ const char* str = lua_tostring(L, 4);
+ count = strlen(str)+1;
+ data = malloc(imDataTypeSize(data_type) * count);
+ memcpy(data, str, count);
+ }
+ else
+ {
+ imbyte *data_byte = (imbyte*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_byte[i] = (imbyte)luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *data_ushort = (imushort*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_ushort[i] = (imushort)luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *data_int = (int*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_int[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_float[i] = (float) luaL_checknumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ int two;
+ float *value = imlua_toarrayfloat(L, -1, &two, 1);
+ if (two != 2)
+ {
+ free(value);
+ luaL_argerror(L, 4, "invalid value");
+ }
+
+ data_float[i] = value[0];
+ data_float[i+1] = value[1];
+ free(value);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+ }
+ }
+
+ imImageSetAttribute(image, attrib, data_type, count, data);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:GetAttribute(attrib)
+\*****************************************************************************/
+static int imluaImageGetAttribute (lua_State *L)
+{
+ int data_type;
+ int i, count;
+ const void *data;
+ int as_string = 0;
+
+ imImage* image = imlua_checkimage(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+
+ data = imImageGetAttribute(image, attrib, &data_type, &count);
+ if (!data)
+ {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ if (data_type == IM_BYTE && lua_isboolean(L, 3))
+ as_string = lua_toboolean(L, 3);
+
+ if (!as_string)
+ lua_newtable(L);
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (as_string)
+ {
+ lua_pushstring(L, (const char*)data);
+ }
+ else
+ {
+ imbyte *data_byte = (imbyte*) data;
+ for (i = 0; i < count; i++, data_byte++)
+ {
+ lua_pushnumber(L, *data_byte);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *data_ushort = (imushort*) data;
+ for (i = 0; i < count; i++, data_ushort += 2)
+ {
+ lua_pushnumber(L, *data_ushort);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *data_int = (int*) data;
+ for (i = 0; i < count; i++, data_int++)
+ {
+ lua_pushnumber(L, *data_int);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float++)
+ {
+ lua_pushnumber(L, *data_float);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float += 2)
+ {
+ imlua_newarrayfloat(L, data_float, 2, 1);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+ }
+
+ lua_pushnumber(L, data_type);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ image:GetAttributeList()
+\*****************************************************************************/
+static int imluaImageGetAttributeList (lua_State *L)
+{
+ int i, attrib_count;
+ char **attrib;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imImageGetAttributeList(image, NULL, &attrib_count);
+
+ attrib = (char**) malloc(attrib_count * sizeof(char*));
+
+ imImageGetAttributeList(image, attrib, &attrib_count);
+
+ lua_newtable(L);
+ for (i = 0; i < attrib_count; i++)
+ {
+ lua_pushstring(L, attrib[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Clear()
+\*****************************************************************************/
+static int imluaImageClear (lua_State *L)
+{
+ imImageClear(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:isBitmap()
+\*****************************************************************************/
+static int imluaImageIsBitmap (lua_State *L)
+{
+ lua_pushboolean(L, imImageIsBitmap(imlua_checkimage(L, 1)));
+ return 1;
+}
+
+
+/*****************************************************************************\
+ image:GetOpenGLData()
+\*****************************************************************************/
+static int imluaImageGetOpenGLData (lua_State *L)
+{
+ int format;
+ imbyte* gldata;
+ imImage *image = imlua_checkimage(L, 1);
+
+ gldata = imImageGetOpenGLData(image, &format);
+ if (!gldata)
+ {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ lua_pushlightuserdata(L, gldata);
+ lua_pushinteger(L, format);
+ return 2;
+}
+
+/*****************************************************************************\
+ image:GetPalette()
+\*****************************************************************************/
+static int imluaImageGetPalette (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ long* color = malloc(sizeof(long) * 256);
+ memcpy(color, image->palette, sizeof(long) * 256);
+ imlua_pushpalette(L, color, 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:SetPalette
+\*****************************************************************************/
+static int imluaImageSetPalette (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ imluaPalette *pal = imlua_checkpalette(L, 2);
+ long* palette = (long*)malloc(sizeof(long)*256);
+ memcpy(palette, pal->color, pal->count*sizeof(long));
+ imImageSetPalette(image, palette, pal->count);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:CopyAttributes(dst_image)
+\*****************************************************************************/
+static int imluaImageCopyAttributes (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imImageCopyAttributes(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:MatchSize(image2)
+\*****************************************************************************/
+static int imluaImageMatchSize (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchSize(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:MatchColor(image2)
+\*****************************************************************************/
+static int imluaImageMatchColor (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchColor(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:MatchDataType(image2)
+\*****************************************************************************/
+static int imluaImageMatchDataType (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchDataType(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:MatchColorSpace(image2)
+\*****************************************************************************/
+static int imluaImageMatchColorSpace (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchColorSpace(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Match(image2)
+\*****************************************************************************/
+static int imluaImageMatch (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatch(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:SetBinary()
+\*****************************************************************************/
+static int imluaImageSetBinary (lua_State *L)
+{
+ imImageSetBinary(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:MakeBinary()
+\*****************************************************************************/
+static int imluaImageMakeBinary (lua_State *L)
+{
+ imImageMakeBinary(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:MakeGray()
+\*****************************************************************************/
+static int imluaImageMakeGray (lua_State *L)
+{
+ imImageMakeGray(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Width()
+\*****************************************************************************/
+static int imluaImageWidth(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->width);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Height()
+\*****************************************************************************/
+static int imluaImageHeight(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->height);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Depth()
+\*****************************************************************************/
+static int imluaImageDepth(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->depth);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:DataType()
+\*****************************************************************************/
+static int imluaImageDataType(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->data_type);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:ColorSpace()
+\*****************************************************************************/
+static int imluaImageColorSpace(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->color_space);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:HasAlpha()
+\*****************************************************************************/
+static int imluaImageHasAlpha(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->has_alpha);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.FileImageLoad(filename, [index])
+\*****************************************************************************/
+static int imluaFileImageLoad (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileImageLoad(filename, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ im.FileImageLoadRegion(filename, [index])
+\*****************************************************************************/
+static int imluaFileImageLoadRegion (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int index = luaL_checkint(L, 2);
+ int bitmap = luaL_checkint(L, 3);
+ int xmin = luaL_checkint(L, 4);
+ int xmax = luaL_checkint(L, 5);
+ int ymin = luaL_checkint(L, 6);
+ int ymax = luaL_checkint(L, 7);
+ int width = luaL_checkint(L, 8);
+ int height = luaL_checkint(L, 9);
+ int error;
+ imImage *image = imFileImageLoadRegion(filename, index, bitmap, &error, xmin, xmax, ymin, ymax, width, height);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ im.FileImageLoadBitmap(filename, [index])
+\*****************************************************************************/
+static int imluaFileImageLoadBitmap (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileImageLoadBitmap(filename, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ im.FileImageSave(filename, format, image)
+\*****************************************************************************/
+static int imluaFileImageSave (lua_State *L)
+{
+ const char *file_name = luaL_checkstring(L, 1);
+ const char *format = luaL_checkstring(L, 2);
+ imImage *image = imlua_checkimage(L, 3);
+
+ imlua_pusherror(L, imFileImageSave(file_name, format, image));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Save(filename, format)
+\*****************************************************************************/
+static int imluaImageSave (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ const char *file_name = luaL_checkstring(L, 2);
+ const char *format = luaL_checkstring(L, 3);
+
+ imlua_pusherror(L, imFileImageSave(file_name, format, image));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Destroy()
+\*****************************************************************************/
+static int imluaImageDestroy (lua_State *L)
+{
+ imImage** image_p = imlua_rawcheckimage(L, 1);
+ if (!(*image_p))
+ luaL_argerror(L, 1, "destroyed imImage");
+
+ imImageDestroy(*image_p);
+ *image_p = NULL; /* mark as destroyed */
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaImage_gc (lua_State *L)
+{
+ imImage** image_p = imlua_rawcheckimage(L, 1);
+ if (*image_p)
+ {
+ imImageDestroy(*image_p);
+ *image_p = NULL; /* mark as destroyed */
+ }
+
+ return 0;
+}
+
+/*****************************************************************************\
+ image tostring
+\*****************************************************************************/
+static int imluaImage_tostring (lua_State *L)
+{
+ imImage** image_p = (imImage**)lua_touserdata(L, 1);
+ if (*image_p)
+ {
+ imImage *image = *image_p;
+ lua_pushfstring(L, "imImage(%p) [width=%d,height=%d,color_space=%s,data_type=%s,depth=%d]",
+ image_p,
+ image->width,
+ image->height,
+ imColorModeSpaceName(image->color_space),
+ imDataTypeName(image->data_type),
+ image->depth
+ );
+ }
+ else
+ {
+ lua_pushfstring(L, "imImage(%p)-destroyed", image_p);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ imagechannel tostring
+\*****************************************************************************/
+static int imluaImageChannel_tostring (lua_State *L)
+{
+ imluaImageChannel *imagechannel = imlua_checkimagechannel(L, 1);
+ lua_pushfstring(L, "imImageChannel(%p) [channel=%d]",
+ imagechannel,
+ imagechannel->channel
+ );
+ return 1;
+}
+
+/*****************************************************************************\
+ imagerow tostring
+\*****************************************************************************/
+static int imluaImageRow_tostring (lua_State *L)
+{
+ char buff[32];
+ imluaImageRow *imagerow = imlua_checkimagerow(L, 1);
+
+ sprintf(buff, "%p", lua_touserdata(L, 1));
+ lua_pushfstring(L, "imImageRow(%s) [channel=%d,row=%d]",
+ buff,
+ imagerow->channel,
+ imagerow->row
+ );
+ return 1;
+}
+
+/*****************************************************************************\
+ image row indexing
+\*****************************************************************************/
+static int imluaImageRow_index (lua_State *L)
+{
+ int index;
+ imluaImageRow *imagerow = imlua_checkimagerow(L, 1);
+ imImage *image = imagerow->image;
+ int channel = imagerow->channel;
+ int row = imagerow->row;
+ int column = luaL_checkint(L, 2);
+
+ if (column < 0 || column >= imagerow->image->width)
+ luaL_argerror(L, 2, "invalid column, out of bounds");
+
+ index = channel * image->width * image->height + row * image->width + column;
+
+ switch (image->data_type)
+ {
+ case IM_BYTE:
+ {
+ imbyte *bdata = (imbyte*) image->data[0];
+ lua_pushnumber(L, (lua_Number) bdata[index]);
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *udata = (imushort*) image->data[0];
+ lua_pushnumber(L, (lua_Number) udata[index]);
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *idata = (int*) image->data[0];
+ lua_pushnumber(L, (lua_Number) idata[index]);
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *fdata = (float*) image->data[0];
+ lua_pushnumber(L, (lua_Number) fdata[index]);
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *cdata = (float*) image->data[0];
+ imlua_newarrayfloat(L, cdata + (2*index), 2, 1);
+ }
+ break;
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ image row new index
+\*****************************************************************************/
+static int imluaImageRow_newindex (lua_State *L)
+{
+ int index;
+ imluaImageRow *imagerow = imlua_checkimagerow(L, 1);
+ imImage *image = imagerow->image;
+ int channel = imagerow->channel;
+ int row = imagerow->row;
+ int column = luaL_checkint(L, 2);
+
+ if (column < 0 || column >= imagerow->image->width)
+ luaL_argerror(L, 2, "invalid column, out of bounds");
+
+ index = channel * image->width * image->height + row * image->width + column;
+
+ switch (image->data_type)
+ {
+ case IM_BYTE:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ imbyte *bdata = (imbyte*) image->data[0];
+ bdata[index] = (imbyte) value;
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ imushort *udata = (imushort*) image->data[0];
+ udata[index] = (imushort) value;
+ }
+ break;
+
+ case IM_INT:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ int *idata = (int*) image->data[0];
+ idata[index] = (int) value;
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ float *fdata = (float*) image->data[0];
+ fdata[index] = (float) value;
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ int count;
+ float *cdata = (float*) image->data[0];
+ float *value = imlua_toarrayfloat(L, 3, &count, 1);
+ if (count != 2)
+ {
+ free(value);
+ luaL_argerror(L, 3, "invalid value");
+ }
+
+ cdata[2*index] = value[0];
+ cdata[2*index+1] = value[1];
+ free(value);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************\
+ image channel indexing
+\*****************************************************************************/
+static int imluaImageChannel_index (lua_State *L)
+{
+ imluaImageChannel *imagechannel = imlua_checkimagechannel(L, 1);
+ int row = luaL_checkint(L, 2);
+
+ if (row < 0 || row >= imagechannel->image->height)
+ luaL_argerror(L, 2, "invalid row, out of bounds");
+
+ imlua_newimagerow(L, imagechannel->image, imagechannel->channel, row);
+ return 1;
+}
+
+/*****************************************************************************\
+ image indexing
+\*****************************************************************************/
+static int imluaImage_index (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+
+ if (lua_isnumber(L, 2))
+ {
+ /* handle numeric indexing */
+ int channel = luaL_checkint(L, 2);
+
+ /* create channel */
+ if (channel < 0 || channel >= image->depth)
+ luaL_argerror(L, 2, "invalid channel, out of bounds");
+
+ imlua_newimagechannel(L, image, channel);
+ }
+ else if (lua_isstring(L, 2))
+ {
+ /* get raw method */
+ lua_getmetatable(L, 1);
+ lua_pushvalue(L, 2);
+ lua_rawget(L, -2);
+ }
+ else
+ {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static const luaL_reg imimage_lib[] = {
+ {"ImageCreate", imluaImageCreate},
+ {"ImageDestroy", imluaImageDestroy},
+ {"FileImageLoad", imluaFileImageLoad},
+ {"FileImageLoadBitmap", imluaFileImageLoadBitmap},
+ {"FileImageLoadRegion", imluaFileImageLoadRegion},
+ {"FileImageSave", imluaFileImageSave},
+ {NULL, NULL}
+};
+
+static const luaL_reg imimage_metalib[] = {
+ {"Destroy", imluaImageDestroy},
+ {"AddAlpha", imluaImageAddAlpha},
+ {"Reshape", imluaImageReshape},
+ {"Copy", imluaImageCopy},
+ {"CopyData", imluaImageCopyData},
+ {"Duplicate", imluaImageDuplicate},
+ {"Clone", imluaImageClone},
+ {"SetAttribute", imluaImageSetAttribute},
+ {"GetAttribute", imluaImageGetAttribute},
+ {"GetAttributeList", imluaImageGetAttributeList},
+ {"Clear", imluaImageClear},
+ {"IsBitmap", imluaImageIsBitmap},
+ {"GetOpenGLData", imluaImageGetOpenGLData},
+ {"SetPalette", imluaImageSetPalette},
+ {"GetPalette", imluaImageGetPalette},
+ {"CopyAttributes", imluaImageCopyAttributes},
+ {"MatchSize", imluaImageMatchSize},
+ {"MatchColor", imluaImageMatchColor},
+ {"MatchDataType", imluaImageMatchDataType},
+ {"MatchColorSpace", imluaImageMatchColorSpace},
+ {"Match", imluaImageMatch},
+ {"SetBinary", imluaImageSetBinary},
+ {"MakeBinary", imluaImageMakeBinary},
+ {"MakeGray", imluaImageMakeGray},
+ {"Width", imluaImageWidth},
+ {"Height", imluaImageHeight},
+ {"Depth", imluaImageDepth},
+ {"DataType", imluaImageDataType},
+ {"ColorSpace", imluaImageColorSpace},
+ {"HasAlpha", imluaImageHasAlpha},
+ {"Save", imluaImageSave},
+
+ {"__gc", imluaImage_gc},
+ {"__tostring", imluaImage_tostring},
+ {"__index", imluaImage_index},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ luaL_newmetatable(L, "imImageChannel"); /* create new metatable for imImageChannel handles */
+ lua_pushliteral(L, "__index");
+ lua_pushcfunction(L, imluaImageChannel_index);
+ lua_rawset(L, -3);
+ lua_pushliteral(L, "__tostring");
+ lua_pushcfunction(L, imluaImageChannel_tostring);
+ lua_rawset(L, -3);
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+
+ luaL_newmetatable(L, "imImageChannelRow"); /* create new metatable for imImageChannelRow handles */
+ lua_pushliteral(L, "__index");
+ lua_pushcfunction(L, imluaImageRow_index);
+ lua_rawset(L, -3);
+ lua_pushliteral(L, "__newindex");
+ lua_pushcfunction(L, imluaImageRow_newindex);
+ lua_rawset(L, -3);
+ lua_pushliteral(L, "__tostring");
+ lua_pushcfunction(L, imluaImageRow_tostring);
+ lua_rawset(L, -3);
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+
+ /* Object Oriented Access */
+ luaL_newmetatable(L, "imImage"); /* create new metatable for imImage handles */
+ lua_pushliteral(L, "__index"); /* dummy code because imluaImage_index will overwrite this behavior */
+ lua_pushvalue(L, -2); /* push metatable */
+ lua_rawset(L, -3); /* metatable.__index = metatable */
+ luaL_register(L, NULL, imimage_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+void imlua_open_image (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ createmeta(L);
+ luaL_register(L, NULL, imimage_lib);
+#ifdef TEC_BIGENDIAN
+#ifdef TEC_64
+#include "loh/im_image_be64.loh"
+#else
+#include "loh/im_image_be32.loh"
+#endif
+#else
+#ifdef TEC_64
+#ifdef WIN64
+#include "loh/im_image_le64w.loh"
+#else
+#include "loh/im_image_le64.loh"
+#endif
+#else
+#include "loh/im_image.loh"
+#endif
+#endif
+}
diff --git a/im/src/lua5/imlua_image.h b/im/src/lua5/imlua_image.h
new file mode 100755
index 0000000..0a39863
--- /dev/null
+++ b/im/src/lua5/imlua_image.h
@@ -0,0 +1,38 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_image.h,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#ifndef __IMLUA_IMAGE_H
+#define __IMLUA_IMAGE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+typedef struct _imluaImageChannel {
+ imImage *image;
+ int channel;
+} imluaImageChannel;
+
+typedef struct _imluaImageRow {
+ imImage *image;
+ int channel;
+ int row;
+} imluaImageRow;
+
+void imlua_open_image(lua_State *L);
+
+int imlua_pushimageerror(lua_State *L, imImage* image, int error);
+void imlua_pushimage(lua_State *L, imImage* image);
+imImage* imlua_checkimage(lua_State *L, int param);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/im/src/lua5/imlua_jp2.c b/im/src/lua5/imlua_jp2.c
new file mode 100755
index 0000000..d69ba7e
--- /dev/null
+++ b/im/src/lua5/imlua_jp2.c
@@ -0,0 +1,44 @@
+/** \file
+ * \brief jp2 format Lua 5 Binding
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "im_format_jp2.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+
+static int imlua_FormatRegisterJP2(lua_State *L)
+{
+ (void)L;
+ imFormatRegisterJP2();
+ return 0;
+}
+
+static const struct luaL_reg imlib[] = {
+ {"FormatRegisterJP2", imlua_FormatRegisterJP2},
+ {NULL, NULL},
+};
+
+
+static int imlua_jp2_open (lua_State *L)
+{
+ imFormatRegisterJP2();
+ luaL_register(L, "im", imlib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_jp2(lua_State* L)
+{
+ return imlua_jp2_open(L);
+}
+
+int luaopen_imlua_jp251(lua_State* L)
+{
+ return imlua_jp2_open(L);
+}
diff --git a/im/src/lua5/imlua_jp2.def b/im/src/lua5/imlua_jp2.def
new file mode 100755
index 0000000..29aa05c
--- /dev/null
+++ b/im/src/lua5/imlua_jp2.def
@@ -0,0 +1,4 @@
+EXPORTS
+ luaopen_imlua_jp2
+ luaopen_imlua_jp251
+ \ No newline at end of file
diff --git a/im/src/lua5/imlua_kernel.c b/im/src/lua5/imlua_kernel.c
new file mode 100755
index 0000000..770a989
--- /dev/null
+++ b/im/src/lua5/imlua_kernel.c
@@ -0,0 +1,182 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_kernel.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <memory.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_process.h"
+#include "im_util.h"
+#include "im_kernel.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+static int imluaKernelSobel(lua_State *L)
+{
+ imlua_pushimage(L, imKernelSobel());
+ return 1;
+}
+
+static int imluaKernelPrewitt(lua_State *L)
+{
+ imlua_pushimage(L, imKernelPrewitt());
+ return 1;
+}
+
+static int imluaKernelKirsh(lua_State *L)
+{
+ imlua_pushimage(L, imKernelKirsh());
+ return 1;
+}
+
+static int imluaKernelLaplacian4(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian4());
+ return 1;
+}
+
+static int imluaKernelLaplacian8(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian8());
+ return 1;
+}
+
+static int imluaKernelLaplacian5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian5x5());
+ return 1;
+}
+
+static int imluaKernelLaplacian7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian7x7());
+ return 1;
+}
+
+static int imluaKernelGradian3x3(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGradian3x3());
+ return 1;
+}
+
+static int imluaKernelGradian7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGradian7x7());
+ return 1;
+}
+
+static int imluaKernelSculpt(lua_State *L)
+{
+ imlua_pushimage(L, imKernelSculpt());
+ return 1;
+}
+
+static int imluaKernelMean3x3(lua_State *L)
+{
+ imlua_pushimage(L, imKernelMean3x3());
+ return 1;
+}
+
+static int imluaKernelMean5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelMean5x5());
+ return 1;
+}
+
+static int imluaKernelCircularMean5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelCircularMean5x5());
+ return 1;
+}
+
+static int imluaKernelMean7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelMean7x7());
+ return 1;
+}
+
+static int imluaKernelCircularMean7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelCircularMean7x7());
+ return 1;
+}
+
+static int imluaKernelGaussian3x3(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGaussian3x3());
+ return 1;
+}
+
+static int imluaKernelGaussian5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGaussian5x5());
+ return 1;
+}
+
+static int imluaKernelBarlett5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelBarlett5x5());
+ return 1;
+}
+
+static int imluaKernelTopHat5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelTopHat5x5());
+ return 1;
+}
+
+static int imluaKernelTopHat7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelTopHat7x7());
+ return 1;
+}
+
+static int imluaKernelEnhance(lua_State *L)
+{
+ imlua_pushimage(L, imKernelEnhance());
+ return 1;
+}
+
+
+static const luaL_reg imkernel_lib[] = {
+ {"KernelSobel", imluaKernelSobel},
+ {"KernelPrewitt", imluaKernelPrewitt},
+ {"KernelKirsh", imluaKernelKirsh},
+ {"KernelLaplacian4", imluaKernelLaplacian4},
+ {"KernelLaplacian8", imluaKernelLaplacian8},
+ {"KernelLaplacian5x5", imluaKernelLaplacian5x5},
+ {"KernelLaplacian7x7", imluaKernelLaplacian7x7},
+ {"KernelGradian3x3", imluaKernelGradian3x3},
+ {"KernelGradian7x7", imluaKernelGradian7x7},
+ {"KernelSculpt", imluaKernelSculpt},
+ {"KernelMean3x3", imluaKernelMean3x3},
+ {"KernelMean5x5", imluaKernelMean5x5},
+ {"KernelCircularMean5x5", imluaKernelCircularMean5x5},
+ {"KernelMean7x7", imluaKernelMean7x7},
+ {"KernelCircularMean7x7", imluaKernelCircularMean7x7},
+ {"KernelGaussian3x3", imluaKernelGaussian3x3},
+ {"KernelGaussian5x5", imluaKernelGaussian5x5},
+ {"KernelBarlett5x5", imluaKernelBarlett5x5},
+ {"KernelTopHat5x5", imluaKernelTopHat5x5},
+ {"KernelTopHat7x7", imluaKernelTopHat7x7},
+ {"KernelEnhance", imluaKernelEnhance},
+ {NULL, NULL}
+};
+
+void imlua_open_kernel (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ luaL_register(L, NULL, imkernel_lib);
+}
diff --git a/im/src/lua5/imlua_palette.c b/im/src/lua5/imlua_palette.c
new file mode 100755
index 0000000..80d23eb
--- /dev/null
+++ b/im/src/lua5/imlua_palette.c
@@ -0,0 +1,399 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_palette.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+#include "im_palette.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_palette.h"
+
+
+static imluaPalette* imlua_rawcheckpalette(lua_State *L, int param)
+{
+ void *p = lua_touserdata(L, param);
+ if (p != NULL) { /* value is a userdata? */
+ if (lua_getmetatable(L, param)) { /* does it have a metatable? */
+ lua_getfield(L, LUA_REGISTRYINDEX, "imPalette"); /* get correct metatable */
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return (imluaPalette*)p;
+ }
+ lua_pop(L, 1); /* remove previous metatable */
+
+ /* check also for CD palette */
+ lua_getfield(L, LUA_REGISTRYINDEX, "cdPalette"); /* get correct metatable */
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return (imluaPalette*)p;
+ }
+ }
+ }
+ luaL_typerror(L, param, "imPalette"); /* else error */
+ return NULL; /* to avoid warnings */
+}
+
+imluaPalette* imlua_checkpalette (lua_State *L, int param)
+{
+ imluaPalette* pal = imlua_rawcheckpalette(L, param);
+ if (!pal->color)
+ luaL_argerror(L, param, "destroyed imPalette");
+
+ return pal;
+}
+
+void imlua_pushpalette(lua_State *L, long* color, int count)
+{
+ imluaPalette *pal = (imluaPalette*) lua_newuserdata(L, sizeof(imluaPalette));
+ pal->count = count;
+ pal->color = color;
+ luaL_getmetatable(L, "imPalette");
+ lua_setmetatable(L, -2);
+}
+
+/***************************************************************************\
+* Creates a palette as a "imPalette" userdata. A palette can be *
+* considered and treated as a color table. *
+* im.PaletteCreate(count: number) -> (palette: "imPalette") *
+\***************************************************************************/
+static int imluaPaletteCreate(lua_State *L)
+{
+ long* color;
+
+ int count = luaL_optint(L, 1, 256);
+ if (count < 1 || count > 256)
+ luaL_argerror(L, 1, "palette count should be a positive integer and less then 256");
+
+ color = (long*)malloc(256*sizeof(long));
+ memset(color, 0, 256*sizeof(long));
+
+ imlua_pushpalette(L, color, count);
+ return 1;
+}
+
+
+/*****************************************************************************\
+ im.PaletteFindNearest
+\*****************************************************************************/
+static int imluaPaletteFindNearest (lua_State *L)
+{
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ long color = (long int) lua_touserdata(L, 1);
+
+ lua_pushnumber(L, imPaletteFindNearest(pal->color, pal->count, color));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteFindColor
+\*****************************************************************************/
+static int imluaPaletteFindColor (lua_State *L)
+{
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ long color = (long) lua_touserdata(L, 2);
+ unsigned char tol = (unsigned char)luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imPaletteFindColor(pal->color, pal->count, color, tol));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteGray
+\*****************************************************************************/
+static int imluaPaletteGray (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteGray(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteRed
+\*****************************************************************************/
+static int imluaPaletteRed (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteRed(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteGreen
+\*****************************************************************************/
+static int imluaPaletteGreen (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteGreen(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteBlue
+\*****************************************************************************/
+static int imluaPaletteBlue (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteBlue(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteYellow
+\*****************************************************************************/
+static int imluaPaletteYellow (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteYellow(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteMagenta
+\*****************************************************************************/
+static int imluaPaletteMagenta (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteMagenta(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteCian
+\*****************************************************************************/
+static int imluaPaletteCian (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteCian(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteRainbow
+\*****************************************************************************/
+static int imluaPaletteRainbow (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteRainbow(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteHues
+\*****************************************************************************/
+static int imluaPaletteHues (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteHues(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteBlueIce
+\*****************************************************************************/
+static int imluaPaletteBlueIce (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteBlueIce(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteHotIron
+\*****************************************************************************/
+static int imluaPaletteHotIron (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteHotIron(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteBlackBody
+\*****************************************************************************/
+static int imluaPaletteBlackBody (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteBlackBody(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteHighContrast
+\*****************************************************************************/
+static int imluaPaletteHighContrast (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteHighContrast(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteUniform
+\*****************************************************************************/
+static int imluaPaletteUniform (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteUniform(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteUniformIndex
+\*****************************************************************************/
+static int imluaPaletteUniformIndex (lua_State *L)
+{
+ lua_pushnumber(L, imPaletteUniformIndex((long int) lua_touserdata(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteUniformIndexHalftoned
+\*****************************************************************************/
+static int imluaPaletteUniformIndexHalftoned (lua_State *L)
+{
+ long color = (long) lua_touserdata(L, 1);
+ int x = luaL_checkint(L, 2);
+ int y = luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imPaletteUniformIndexHalftoned(color, x, y));
+ return 1;
+}
+
+/***************************************************************************\
+* Frees a previously allocated palette *
+* im.PaletteDestroy(palette: "imPalette") *
+\***************************************************************************/
+static int imluaPaletteDestroy (lua_State *L)
+{
+ imluaPalette *pal = imlua_rawcheckpalette(L, 1);
+ if (!pal->color)
+ luaL_argerror(L, 1, "destroyed imPalette");
+
+ free(pal->color);
+ pal->color = NULL; /* mark as destroyed */
+ pal->count = 0;
+
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaPalette_gc(lua_State *L)
+{
+ imluaPalette *pal = (imluaPalette*)lua_touserdata(L, 1);
+ if (pal && pal->color)
+ {
+ free(pal->color);
+ pal->color = NULL; /* mark as destroyed */
+ pal->count = 0;
+ }
+
+ return 0;
+}
+
+/***************************************************************************\
+* color = palette[i] *
+\***************************************************************************/
+static int imluaPalette_index(lua_State *L)
+{
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ int index_i = luaL_checkint(L, 2);
+
+ if (index_i < 0 || index_i >= pal->count)
+ luaL_argerror(L, 2, "index is out of bounds");
+
+ lua_pushlightuserdata(L, (void*) pal->color[index_i]);
+ return 1;
+}
+
+/***************************************************************************\
+* palette[i] = color *
+\***************************************************************************/
+static int imluaPalette_newindex(lua_State *L)
+{
+ long color_i;
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ int index_i = luaL_checkint(L, 2);
+
+ if (index_i < 0 || index_i >= pal->count)
+ luaL_argerror(L, 2, "index is out of bounds");
+
+ if (!lua_islightuserdata(L, 3))
+ luaL_argerror(L, 3, "color must be a light user data");
+
+ color_i = (long int) lua_touserdata(L, 3);
+
+ pal->color[index_i] = color_i;
+ return 0;
+}
+
+/*****************************************************************************\
+ len
+\*****************************************************************************/
+static int imluaPalette_len(lua_State *L)
+{
+ imluaPalette *pal = (imluaPalette*)lua_touserdata(L, 1);
+ lua_pushinteger(L, pal->count);
+ return 1;
+}
+
+/*****************************************************************************\
+ tostring
+\*****************************************************************************/
+static int imluaPalette_tostring (lua_State *L)
+{
+ imluaPalette *pal = (imluaPalette*)lua_touserdata(L, 1);
+ lua_pushfstring(L, "imPalette(%p)%s", pal, (pal->color)? "": "-destroyed");
+ return 1;
+}
+
+static const luaL_reg impalette_lib[] = {
+ {"PaletteFindNearest", imluaPaletteFindNearest},
+ {"PaletteFindColor", imluaPaletteFindColor},
+ {"PaletteGray", imluaPaletteGray },
+ {"PaletteRed", imluaPaletteRed },
+ {"PaletteGreen", imluaPaletteGreen },
+ {"PaletteBlue", imluaPaletteBlue },
+ {"PaletteYellow", imluaPaletteYellow },
+ {"PaletteMagenta", imluaPaletteMagenta },
+ {"PaletteCian", imluaPaletteCian },
+ {"PaletteRainbow", imluaPaletteRainbow },
+ {"PaletteHues", imluaPaletteHues },
+ {"PaletteBlueIce", imluaPaletteBlueIce },
+ {"PaletteHotIron", imluaPaletteHotIron },
+ {"PaletteBlackBody", imluaPaletteBlackBody },
+ {"PaletteHighContrast", imluaPaletteHighContrast },
+ {"PaletteUniform", imluaPaletteUniform },
+ {"PaletteUniformIndex", imluaPaletteUniformIndex },
+ {"PaletteUniformIndexHalftoned", imluaPaletteUniformIndexHalftoned },
+
+ {"PaletteDestroy", imluaPaletteDestroy},
+ {"PaletteCreate", imluaPaletteCreate},
+
+ {NULL, NULL}
+};
+
+static const luaL_reg impalette_metalib[] = {
+ {"__gc", imluaPalette_gc},
+ {"__tostring", imluaPalette_tostring},
+ {"__index", imluaPalette_index},
+ {"__newindex", imluaPalette_newindex},
+ {"__len", imluaPalette_len},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ /* there is no object orientation for imPalette, only array access */
+ luaL_newmetatable(L, "imPalette"); /* create new metatable for imPalette handles */
+ luaL_register(L, NULL, impalette_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+void imlua_open_palette (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ createmeta(L);
+ luaL_register(L, NULL, impalette_lib);
+}
diff --git a/im/src/lua5/imlua_palette.h b/im/src/lua5/imlua_palette.h
new file mode 100755
index 0000000..453fd01
--- /dev/null
+++ b/im/src/lua5/imlua_palette.h
@@ -0,0 +1,32 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_palette.h,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#ifndef __IMLUA_PALETTE_H
+#define __IMLUA_PALETTE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* this is the same declaration used in the CD toolkit for cdPalette in Lua */
+typedef struct _imPalette {
+ long* color;
+ int count;
+} imluaPalette;
+
+void imlua_pushpalette(lua_State *L, long* color, int count);
+imluaPalette* imlua_checkpalette (lua_State *L, int param);
+
+void imlua_open_palette(lua_State *L);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/im/src/lua5/imlua_process.c b/im/src/lua5/imlua_process.c
new file mode 100755
index 0000000..863c1d6
--- /dev/null
+++ b/im/src/lua5/imlua_process.c
@@ -0,0 +1,3143 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_process.c,v 1.8 2009/10/01 02:56:58 scuri Exp $
+ */
+
+#include <memory.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_process.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+
+/*****************************************************************************\
+ Image Statistics Calculations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.CalcRMSError(image1, image2)
+\*****************************************************************************/
+static int imluaCalcRMSError (lua_State *L)
+{
+ imImage* image1 = imlua_checkimage(L, 1);
+ imImage* image2 = imlua_checkimage(L, 2);
+
+ imlua_match(L, image1, image2);
+
+ lua_pushnumber(L, imCalcRMSError(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcSNR(src_image, noise_image)
+\*****************************************************************************/
+static int imluaCalcSNR (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* noise_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, noise_image);
+
+ lua_pushnumber(L, imCalcSNR(src_image, noise_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcCountColors(src_image)
+\*****************************************************************************/
+static int imluaCalcCountColors (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ if (src_image->color_space >= IM_CMYK)
+ luaL_argerror(L, 1, "color space can be RGB, Gray, Binary or Map only");
+
+ lua_pushnumber(L, imCalcCountColors(src_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcHistogram(src_image, plane, cumulative)
+\*****************************************************************************/
+static int imluaCalcHistogram (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ int plane = luaL_checkint(L, 2);
+ int cumulative = lua_toboolean(L, 3);
+
+ switch (src_image->data_type)
+ {
+ case IM_BYTE:
+ {
+ unsigned long hist[256];
+ imCalcHistogram((imbyte*) src_image->data[plane], src_image->count, hist, cumulative);
+ imlua_newarrayulong(L, hist, 256, 0);
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ unsigned long hist[65535];
+ imCalcUShortHistogram(src_image->data[plane], src_image->count, hist, cumulative);
+ imlua_newarrayulong(L, hist, 65535, 0);
+ }
+ break;
+
+ default:
+ luaL_argerror(L, 1, "data_type can be byte or ushort only");
+ break;
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcGrayHistogram(src_image, cumulative)
+\*****************************************************************************/
+static int imluaCalcGrayHistogram (lua_State *L)
+{
+ unsigned long hist[256];
+ imImage* src_image = imlua_checkimage(L, 1);
+ int cumulative = lua_toboolean(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ if (src_image->color_space >= IM_CMYK)
+ luaL_argerror(L, 1, "color space can be RGB, Gray, Binary or Map only");
+
+ imCalcGrayHistogram(src_image, hist, cumulative);
+ imlua_newarrayulong(L, hist, 256, 0);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcImageStatistics(src_image)
+\*****************************************************************************/
+static int imluaCalcImageStatistics (lua_State *L)
+{
+ imStats stats;
+ imImage *image = imlua_checkimage(L, 1);
+
+ if (image->data_type == IM_CFLOAT)
+ luaL_argerror(L, 1, "data type can NOT be of type cfloat");
+
+ imCalcImageStatistics(image, &stats);
+
+ lua_newtable(L);
+ lua_pushstring(L, "max"); lua_pushnumber(L, stats.max); lua_settable(L, -3);
+ lua_pushstring(L, "min"); lua_pushnumber(L, stats.min); lua_settable(L, -3);
+ lua_pushstring(L, "positive"); lua_pushnumber(L, stats.positive); lua_settable(L, -3);
+ lua_pushstring(L, "negative"); lua_pushnumber(L, stats.negative); lua_settable(L, -3);
+ lua_pushstring(L, "zeros"); lua_pushnumber(L, stats.zeros); lua_settable(L, -3);
+ lua_pushstring(L, "mean"); lua_pushnumber(L, stats.mean); lua_settable(L, -3);
+ lua_pushstring(L, "stddev"); lua_pushnumber(L, stats.stddev); lua_settable(L, -3);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcHistogramStatistics(src_image)
+\*****************************************************************************/
+static int imluaCalcHistogramStatistics (lua_State *L)
+{
+ imStats stats;
+ imImage *image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, image, IM_BYTE);
+
+ imCalcHistogramStatistics(image, &stats);
+
+ lua_newtable(L);
+ lua_pushstring(L, "max"); lua_pushnumber(L, stats.max); lua_settable(L, -3);
+ lua_pushstring(L, "min"); lua_pushnumber(L, stats.min); lua_settable(L, -3);
+ lua_pushstring(L, "positive"); lua_pushnumber(L, stats.positive); lua_settable(L, -3);
+ lua_pushstring(L, "negative"); lua_pushnumber(L, stats.negative); lua_settable(L, -3);
+ lua_pushstring(L, "zeros"); lua_pushnumber(L, stats.zeros); lua_settable(L, -3);
+ lua_pushstring(L, "mean"); lua_pushnumber(L, stats.mean); lua_settable(L, -3);
+ lua_pushstring(L, "stddev"); lua_pushnumber(L, stats.stddev); lua_settable(L, -3);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcHistoImageStatistics
+\*****************************************************************************/
+static int imluaCalcHistoImageStatistics (lua_State *L)
+{
+ int* median;
+ int* mode;
+
+ imImage *image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, image, IM_BYTE);
+
+ median = (int*)malloc(sizeof(int)*image->depth);
+ mode = (int*)malloc(sizeof(int)*image->depth);
+
+ imCalcHistoImageStatistics(image, median, mode);
+
+ imlua_newarrayint (L, median, image->depth, 0);
+ imlua_newarrayint (L, mode, image->depth, 0);
+
+ free(median);
+ free(mode);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ Image Analysis
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.AnalyzeFindRegions(src_image, dst_image, connect, touch_border)
+\*****************************************************************************/
+static int imluaAnalyzeFindRegions (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int connect = luaL_checkint(L, 3);
+ int touch_border = lua_toboolean(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_checktype(L, 2, dst_image, IM_GRAY, IM_USHORT);
+
+ luaL_argcheck(L, (connect == 4 || connect == 8), 3, "invalid connect value, must be 4 or 8");
+ lua_pushnumber(L, imAnalyzeFindRegions(src_image, dst_image, connect, touch_border));
+ return 1;
+}
+
+static int iGetMax(imImage* image)
+{
+ int max = 0;
+ int i;
+
+ imushort* data = (imushort*)image->data[0];
+ for (i = 0; i < image->count; i++)
+ {
+ if (*data > max)
+ max = *data;
+
+ data++;
+ }
+
+ return max;
+}
+
+static int imlua_checkregioncount(lua_State *L, int narg, imImage* image)
+{
+ if (lua_isnoneornil(L, narg)) return iGetMax(image);
+ else return (int)luaL_checknumber(L, narg);
+}
+
+
+/*****************************************************************************\
+ im.AnalyzeMeasureArea(image, [count])
+\*****************************************************************************/
+static int imluaAnalyzeMeasureArea (lua_State *L)
+{
+ int count;
+ int *area;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ count = imlua_checkregioncount(L, 2, image);
+ area = (int*) malloc(sizeof(int) * count);
+
+ imAnalyzeMeasureArea(image, area, count);
+
+ imlua_newarrayint(L, area, count, 0);
+ free(area);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasurePerimArea(image)
+\*****************************************************************************/
+static int imluaAnalyzeMeasurePerimArea (lua_State *L)
+{
+ int count;
+ float *perimarea;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ count = imlua_checkregioncount(L, 2, image);
+ perimarea = (float*) malloc(sizeof(float) * count);
+
+ imAnalyzeMeasurePerimArea(image, perimarea);
+
+ imlua_newarrayfloat (L, perimarea, count, 0);
+ free(perimarea);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasureCentroid(image, [area], [count])
+\*****************************************************************************/
+static int imluaAnalyzeMeasureCentroid (lua_State *L)
+{
+ int count;
+ float *cx, *cy;
+ int *area;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ area = imlua_toarrayint(L, 2, &count, 0);
+ count = imlua_checkregioncount(L, 3, image);
+
+ cx = (float*) malloc (sizeof(float) * count);
+ cy = (float*) malloc (sizeof(float) * count);
+
+ imAnalyzeMeasureCentroid(image, area, count, cx, cy);
+
+ imlua_newarrayfloat(L, cx, count, 0);
+ imlua_newarrayfloat(L, cy, count, 0);
+
+ if (area)
+ free(area);
+ free(cx);
+ free(cy);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasurePrincipalAxis(image, [area], [cx], [cy])
+\*****************************************************************************/
+static int imluaAnalyzeMeasurePrincipalAxis (lua_State *L)
+{
+ int count;
+ float *cx, *cy;
+ int *area;
+ float *major_slope, *major_length, *minor_slope, *minor_length;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ area = imlua_toarrayint(L, 2, &count, 0);
+ cx = imlua_toarrayfloat(L, 3, NULL, 0);
+ cy = imlua_toarrayfloat(L, 4, NULL, 0);
+ count = imlua_checkregioncount(L, 5, image);
+
+ major_slope = (float*) malloc (sizeof(float) * count);
+ major_length = (float*) malloc (sizeof(float) * count);
+ minor_slope = (float*) malloc (sizeof(float) * count);
+ minor_length = (float*) malloc (sizeof(float) * count);
+
+ imAnalyzeMeasurePrincipalAxis(image, area, cx, cy, count, major_slope, major_length, minor_slope, minor_length);
+
+ imlua_newarrayfloat(L, major_slope, count, 0);
+ imlua_newarrayfloat(L, major_length, count, 0);
+ imlua_newarrayfloat(L, minor_slope, count, 0);
+ imlua_newarrayfloat(L, minor_length, count, 0);
+
+ if (area)
+ free(area);
+ if (cx)
+ free(cx);
+ if (cy)
+ free(cy);
+
+ free(major_slope);
+ free(major_length);
+ free(minor_slope);
+ free(minor_length);
+
+ return 4;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasureHoles
+\*****************************************************************************/
+static int imluaAnalyzeMeasureHoles (lua_State *L)
+{
+ int holes_count, count;
+ int connect;
+ int *area = NULL;
+ float *perim = NULL;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ connect = luaL_checkint(L, 2);
+ count = imlua_checkregioncount(L, 3, image);
+
+ area = (int*) malloc (sizeof(int) * count);
+ perim = (float*) malloc (sizeof(float) * count);
+
+ imAnalyzeMeasureHoles(image, connect, &holes_count, area, perim);
+
+ lua_pushnumber(L, holes_count);
+ imlua_newarrayint(L, area, holes_count, 0);
+ imlua_newarrayfloat(L, perim, holes_count, 0);
+
+ if (area)
+ free(area);
+ if (perim)
+ free(perim);
+
+ return 3;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasurePerimeter(image, [count])
+\*****************************************************************************/
+static int imluaAnalyzeMeasurePerimeter (lua_State *L)
+{
+ int count;
+ float *perim;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ count = imlua_checkregioncount(L, 2, image);
+ perim = (float*) malloc(sizeof(float) * count);
+
+ imAnalyzeMeasurePerimeter(image, perim, count);
+
+ imlua_newarrayfloat(L, perim, count, 0);
+
+ free(perim);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessPerimeterLine(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessPerimeterLine (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_match(L, src_image, dst_image);
+
+ imProcessPerimeterLine(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessRemoveByArea(src_image, dst_image, connect, start_size, end_size, inside)
+\*****************************************************************************/
+static int imluaProcessRemoveByArea (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int connect = luaL_checkint(L, 3);
+ int start_size = luaL_checkint(L, 4);
+ int end_size = luaL_checkint(L, 5);
+ int inside = lua_toboolean(L, 6);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (connect == 4 || connect == 8), 3, "invalid connect value, must be 4 or 8");
+
+ imProcessRemoveByArea(src_image, dst_image, connect, start_size, end_size, inside);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessFillHoles(src_image, dst_image, connect)
+\*****************************************************************************/
+static int imluaProcessFillHoles (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int connect = luaL_checkint(L, 3);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (connect == 4 || connect == 8), 3, "invalid connect value, must be 4 or 8");
+
+ imProcessFillHoles(src_image, dst_image, connect);
+ return 0;
+}
+
+static void imlua_checkhoughsize(lua_State *L, imImage* image, imImage* hough_image, int param)
+{
+#define IMSQR(_x) (_x*_x)
+ int hough_rmax;
+ if (hough_image->width != 180)
+ luaL_argerror(L, param, "invalid image width");
+
+ hough_rmax = (int)(sqrt((double)(IMSQR(image->width) + IMSQR(image->height)))/2.0);
+ if (hough_image->height != 2*hough_rmax+1)
+ luaL_argerror(L, param, "invalid image height");
+}
+
+/*****************************************************************************\
+ im.ProcessHoughLines(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessHoughLines (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_checktype(L, 2, dst_image, IM_GRAY, IM_INT);
+ imlua_checkhoughsize(L, src_image, dst_image, 2);
+
+ lua_pushboolean(L, imProcessHoughLines(src_image, dst_image));
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessHoughLinesDraw(src_image, hough_points, dst_image)
+\*****************************************************************************/
+static int imluaProcessHoughLinesDraw (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* hough_points = imlua_checkimage(L, 3);
+ imImage* dst_image = imlua_checkimage(L, 4);
+ imImage* hough = NULL;
+ if (lua_isuserdata(L, 2))
+ {
+ hough = imlua_checkimage(L, 2);
+ imlua_checktype(L, 2, hough, IM_GRAY, IM_INT);
+ imlua_checkhoughsize(L, src_image, hough, 2);
+ }
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 3, hough_points, IM_BINARY);
+ imlua_checkhoughsize(L, src_image, hough_points, 3);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushnumber(L, imProcessHoughLinesDraw(src_image, hough, hough_points, dst_image));
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessDistanceTransform(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessDistanceTransform (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_checkdatatype(L, 2, dst_image, IM_FLOAT);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessDistanceTransform(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessRegionalMaximum(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessRegionalMaximum (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_FLOAT);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessRegionalMaximum(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ Image Resize
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessReduce(src_image, dst_image, order)
+\*****************************************************************************/
+static int imluaProcessReduce (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int order = luaL_checkint(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1), 3, "invalid order, must be 0 or 1");
+
+ lua_pushboolean(L, imProcessReduce(src_image, dst_image, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessResize(src_image, dst_image, order)
+\*****************************************************************************/
+static int imluaProcessResize (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int order = luaL_checkint(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 3, "invalid order, must be 0, 1 or 3");
+
+ lua_pushboolean(L, imProcessResize(src_image, dst_image, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessReduceBy4(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessReduceBy4 (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L,
+ dst_image->width == (src_image->width / 2) &&
+ dst_image->height == (src_image->height / 2), 3, "destiny image size must be source image width/2, height/2");
+
+ imProcessReduceBy4(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessCrop(src_image, dst_image, xmin, ymin)
+\*****************************************************************************/
+static int imluaProcessCrop (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int xmin = luaL_checkint(L, 3);
+ int ymin = luaL_checkint(L, 4);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, xmin >= 0 && xmin < src_image->width, 3, "xmin must be >= 0 and < width");
+ luaL_argcheck(L, ymin >= 0 && ymin < src_image->height, 4, "ymin must be >= 0 and < height");
+ luaL_argcheck(L, dst_image->width <= (src_image->width - xmin), 2, "destiny image size must be smaller than source image width-xmin");
+ luaL_argcheck(L, dst_image->height <= (src_image->height - ymin), 2, "destiny image size must be smaller than source image height-ymin");
+
+ imProcessCrop(src_image, dst_image, xmin, ymin);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessInsert(src_image, region_image, dst_image, xmin, ymin)
+\*****************************************************************************/
+static int imluaProcessInsert (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* region_image = imlua_checkimage(L, 2);
+ imImage* dst_image = imlua_checkimage(L, 3);
+ int xmin = luaL_checkint(L, 4);
+ int ymin = luaL_checkint(L, 5);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, xmin >= 0 && xmin < src_image->width, 3, "xmin must be >= 0 and < width");
+ luaL_argcheck(L, ymin >= 0 && ymin < src_image->height, 3, "ymin must be >= 0 and < height");
+
+ imProcessInsert(src_image, region_image, dst_image, xmin, ymin);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessAddMargins(src_image, dst_image, xmin, ymin)
+\*****************************************************************************/
+static int imluaProcessAddMargins (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int xmin = luaL_checkint(L, 3);
+ int ymin = luaL_checkint(L, 4);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, dst_image->width > (src_image->width + xmin), 2, "destiny image size must be greatter than source image width+xmin, height+ymin");
+ luaL_argcheck(L, dst_image->height > (src_image->height + ymin), 2, "destiny image size must be greatter than source image width+xmin, height+ymin");
+
+ imProcessAddMargins(src_image, dst_image, xmin, ymin);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Geometric Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessCalcRotateSize
+\*****************************************************************************/
+static int imluaProcessCalcRotateSize (lua_State *L)
+{
+ int new_width, new_height;
+
+ int width = luaL_checkint(L, 1);
+ int height = luaL_checkint(L, 2);
+ double cos0 = (double) luaL_checknumber(L, 3);
+ double sin0 = (double) luaL_checknumber(L, 4);
+
+ imProcessCalcRotateSize(width, height, &new_width, &new_height, cos0, sin0);
+ lua_pushnumber(L, new_width);
+ lua_pushnumber(L, new_height);
+ return 2;
+}
+
+/*****************************************************************************\
+ im.ProcessRotate
+\*****************************************************************************/
+static int imluaProcessRotate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ double cos0 = (double) luaL_checknumber(L, 3);
+ double sin0 = (double) luaL_checknumber(L, 4);
+ int order = luaL_checkint(L, 5);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 5, "invalid order, must be 0, 1 or 3");
+
+ lua_pushboolean(L, imProcessRotate(src_image, dst_image, cos0, sin0, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRotateRef
+\*****************************************************************************/
+static int imluaProcessRotateRef (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ double cos0 = (double) luaL_checknumber(L, 3);
+ double sin0 = (double) luaL_checknumber(L, 4);
+ int x = luaL_checkint(L, 5);
+ int y = luaL_checkint(L, 6);
+ int to_origin = lua_toboolean(L, 7);
+ int order = luaL_checkint(L, 8);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 5, "invalid order, must be 0, 1, or 3");
+
+ lua_pushboolean(L, imProcessRotateRef(src_image, dst_image, cos0, sin0, x, y, to_origin, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRotate90
+\*****************************************************************************/
+static int imluaProcessRotate90 (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int dir = lua_toboolean(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, dst_image->width == src_image->height && dst_image->height == src_image->width, 2, "destiny width and height must have the source height and width");
+ luaL_argcheck(L, (dir == -1 || dir == 1), 3, "invalid dir, can be -1 or 1 only");
+
+ imProcessRotate90(src_image, dst_image, dir);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessRotate180
+\*****************************************************************************/
+static int imluaProcessRotate180 (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessRotate180(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMirror
+\*****************************************************************************/
+static int imluaProcessMirror (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessMirror(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessFlip
+\*****************************************************************************/
+static int imluaProcessFlip (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessFlip(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessInterlaceSplit
+\*****************************************************************************/
+static int imluaProcessInterlaceSplit (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image1 = imlua_checkimage(L, 2);
+ imImage *dst_image2 = imlua_checkimage(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image1);
+ imlua_matchcolor(L, src_image, dst_image2);
+ luaL_argcheck(L, dst_image1->width == src_image->width && dst_image2->width == src_image->width, 2, "destiny width must be equal to source width");
+
+ if (src_image->height%2)
+ {
+ int dst_height1 = src_image->height/2 + 1;
+ luaL_argcheck(L, dst_image1->height == dst_height1, 2, "destiny1 height must be equal to source height/2+1 if height odd");
+ }
+ else
+ luaL_argcheck(L, dst_image1->height == src_image->height/2, 2, "destiny1 height must be equal to source height/2 if height even");
+
+ luaL_argcheck(L, dst_image2->height == src_image->height/2, 2, "destiny2 height must be equal to source height/2");
+
+ imProcessInterlaceSplit(src_image, dst_image1, dst_image2);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessRadial
+\*****************************************************************************/
+static int imluaProcessRadial (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float k1 = (float) luaL_checknumber(L, 3);
+ int order = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 4, "invalid order");
+
+ lua_pushboolean(L, imProcessRadial(src_image, dst_image, k1, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSwirl
+\*****************************************************************************/
+static int imluaProcessSwirl(lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float k1 = (float) luaL_checknumber(L, 3);
+ int order = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 4, "invalid order, can be 0, 1 or 3");
+
+ lua_pushboolean(L, imProcessSwirl(src_image, dst_image, k1, order));
+ return 1;
+}
+
+static void imlua_checknotcfloat(lua_State *L, imImage *image, int index)
+{
+ if (image->data_type == IM_CFLOAT)
+ luaL_argerror(L, index, "image data type can NOT be cfloat");
+}
+
+
+/*****************************************************************************\
+ Morphology Operations for Gray Images
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessGrayMorphConvolve
+\*****************************************************************************/
+static int imluaProcessGrayMorphConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+ int ismax = lua_toboolean(L, 4);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+ imlua_checkdatatype(L, 3, kernel, IM_INT);
+ imlua_matchsize(L, src_image, kernel);
+
+ lua_pushboolean(L, imProcessGrayMorphConvolve(src_image, dst_image, kernel, ismax));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphErode
+\*****************************************************************************/
+static int imluaProcessGrayMorphErode (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphErode(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphDilate
+\*****************************************************************************/
+static int imluaProcessGrayMorphDilate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphDilate(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphOpen
+\*****************************************************************************/
+static int imluaProcessGrayMorphOpen (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphOpen(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphClose
+\*****************************************************************************/
+static int imluaProcessGrayMorphClose (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphClose(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphTopHat
+\*****************************************************************************/
+static int imluaProcessGrayMorphTopHat (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphTopHat(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphWell
+\*****************************************************************************/
+static int imluaProcessGrayMorphWell (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphWell(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphGradient
+\*****************************************************************************/
+static int imluaProcessGrayMorphGradient (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphGradient(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+
+
+/*****************************************************************************\
+ Morphology Operations for Binary Images
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessBinMorphConvolve
+\*****************************************************************************/
+static int imluaProcessBinMorphConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+ int hit_white = lua_toboolean(L, 4);
+ int iter = luaL_checkint(L, 5);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+ imlua_checkdatatype(L, 3, kernel, IM_INT);
+ imlua_matchsize(L, src_image, kernel);
+
+ lua_pushboolean(L, imProcessBinMorphConvolve(src_image, dst_image, kernel, hit_white, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphErode
+\*****************************************************************************/
+static int imluaProcessBinMorphErode (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphErode(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphDilate
+\*****************************************************************************/
+static int imluaProcessBinMorphDilate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphDilate(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphOpen
+\*****************************************************************************/
+static int imluaProcessBinMorphOpen (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphOpen(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphClose
+\*****************************************************************************/
+static int imluaProcessBinMorphClose (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphClose(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphOutline
+\*****************************************************************************/
+static int imluaProcessBinMorphOutline (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphOutline(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphThin
+\*****************************************************************************/
+static int imluaProcessBinMorphThin (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBinMorphThin(src_image, dst_image);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Rank Convolution Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessMedianConvolve
+\*****************************************************************************/
+static int imluaProcessMedianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessMedianConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRangeConvolve
+\*****************************************************************************/
+static int imluaProcessRangeConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRangeConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRankClosestConvolve
+\*****************************************************************************/
+static int imluaProcessRankClosestConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRankClosestConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRankMaxConvolve
+\*****************************************************************************/
+static int imluaProcessRankMaxConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRankMaxConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRankMinConvolve
+\*****************************************************************************/
+static int imluaProcessRankMinConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRankMinConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+
+/*****************************************************************************\
+ Convolution Operations
+\*****************************************************************************/
+
+static void imlua_checkkernel(lua_State *L, imImage* kernel, int index)
+{
+ imlua_checkcolorspace(L, index, kernel, IM_GRAY);
+ luaL_argcheck(L, kernel->data_type == IM_INT || kernel->data_type == IM_FLOAT, index, "kernel data type can be int or float only");
+}
+
+/*****************************************************************************\
+ im.ProcessConvolve
+\*****************************************************************************/
+static int imluaProcessConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessConvolve(src_image, dst_image, kernel));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessConvolveDual
+\*****************************************************************************/
+static int imluaProcessConvolveDual (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel1 = imlua_checkimage(L, 3);
+ imImage *kernel2 = imlua_checkimage(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel1, 3);
+ imlua_checkkernel(L, kernel2, 4);
+
+ lua_pushboolean(L, imProcessConvolveDual(src_image, dst_image, kernel1, kernel2));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessConvolveRep
+\*****************************************************************************/
+static int imluaProcessConvolveRep (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+ int count = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessConvolveRep(src_image, dst_image, kernel, count));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessConvolveSep
+\*****************************************************************************/
+static int imluaProcessConvolveSep (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessConvolveSep(src_image, dst_image, kernel));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessCompassConvolve
+\*****************************************************************************/
+static int imluaProcessCompassConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessCompassConvolve(src_image, dst_image, kernel));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRotateKernel
+\*****************************************************************************/
+static int imluaProcessRotateKernel (lua_State *L)
+{
+ imProcessRotateKernel(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessDiffOfGaussianConvolve
+\*****************************************************************************/
+static int imluaProcessDiffOfGaussianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev1 = (float) luaL_checknumber(L, 3);
+ float stddev2 = (float) luaL_checknumber(L, 4);
+
+ if (src_image->data_type == IM_BYTE || src_image->data_type == IM_USHORT)
+ {
+ imlua_matchcolor(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_INT);
+ }
+ else
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessDiffOfGaussianConvolve(src_image, dst_image, stddev1, stddev2));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessLapOfGaussianConvolve
+\*****************************************************************************/
+static int imluaProcessLapOfGaussianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev = (float) luaL_checknumber(L, 3);
+
+ if (src_image->data_type == IM_BYTE || src_image->data_type == IM_USHORT)
+ {
+ imlua_matchcolor(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_INT);
+ }
+ else
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessLapOfGaussianConvolve(src_image, dst_image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessMeanConvolve
+\*****************************************************************************/
+static int imluaProcessMeanConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessMeanConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBarlettConvolve
+\*****************************************************************************/
+static int imluaProcessBarlettConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBarlettConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGaussianConvolve
+\*****************************************************************************/
+static int imluaProcessGaussianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev = (float) luaL_checknumber(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGaussianConvolve(src_image, dst_image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessPrewittConvolve
+\*****************************************************************************/
+static int imluaProcessPrewittConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessPrewittConvolve(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSplineEdgeConvolve
+\*****************************************************************************/
+static int imluaProcessSplineEdgeConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessSplineEdgeConvolve(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSobelConvolve
+\*****************************************************************************/
+static int imluaProcessSobelConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessSobelConvolve(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessZeroCrossing
+\*****************************************************************************/
+static int imluaProcessZeroCrossing (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L, src_image->data_type == IM_INT || src_image->data_type == IM_FLOAT, 1, "image data type can be int or float only");
+ imlua_match(L, src_image, dst_image);
+
+ imProcessZeroCrossing(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessCanny
+\*****************************************************************************/
+static int imluaProcessCanny (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev = (float) luaL_checknumber(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessCanny(src_image, dst_image, stddev);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessUnsharp
+\*****************************************************************************/
+static int imluaProcessUnsharp(lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float p1 = (float)luaL_checknumber(L, 3);
+ float p2 = (float)luaL_checknumber(L, 4);
+ float p3 = (float)luaL_checknumber(L, 5);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessUnsharp(src_image, dst_image, p1, p2, p3);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSharp
+\*****************************************************************************/
+static int imluaProcessSharp(lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float p1 = (float)luaL_checknumber(L, 3);
+ float p2 = (float)luaL_checknumber(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessSharp(src_image, dst_image, p1, p2);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSharpKernel
+\*****************************************************************************/
+static int imluaProcessSharpKernel(lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *kernel = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ float p1 = (float)luaL_checknumber(L, 4);
+ float p2 = (float)luaL_checknumber(L, 5);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessSharpKernel(src_image, kernel, dst_image, p1, p2);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.GaussianStdDev2Repetitions
+\*****************************************************************************/
+static int imluaGaussianKernelSize2StdDev(lua_State *L)
+{
+ lua_pushnumber(L, imGaussianKernelSize2StdDev((int)luaL_checknumber(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.GaussianStdDev2KernelSize
+\*****************************************************************************/
+static int imluaGaussianStdDev2KernelSize (lua_State *L)
+{
+ lua_pushnumber(L, imGaussianStdDev2KernelSize((float)luaL_checknumber(L, 1)));
+ return 1;
+}
+
+
+
+/*****************************************************************************\
+ Arithmetic Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessUnArithmeticOp
+\*****************************************************************************/
+static int imluaProcessUnArithmeticOp (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int op = luaL_checkint(L, 3);
+
+ imlua_matchcolorspace(L, src_image, dst_image);
+
+ imProcessUnArithmeticOp(src_image, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessArithmeticOp
+\*****************************************************************************/
+static int imluaProcessArithmeticOp (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_matchsize(L, src_image1, dst_image);
+ imlua_matchsize(L, src_image2, dst_image);
+
+ switch (src_image1->data_type)
+ {
+ case IM_BYTE:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_BYTE ||
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is byte, destiny image data type can be byte, ushort, int and float only.");
+ break;
+ case IM_USHORT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is ushort, destiny image data type can be ushort, int and float only.");
+ break;
+ case IM_INT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is int, destiny image data type can be int and float only.");
+ break;
+ case IM_FLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is float, destiny image data type can be float only.");
+ break;
+ case IM_CFLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_CFLOAT,
+ 2, "source image is cfloat, destiny image data type can be cfloat only.");
+ break;
+ }
+
+ imProcessArithmeticOp(src_image1, src_image2, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessArithmeticConstOp
+\*****************************************************************************/
+static int imluaProcessArithmeticConstOp (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ float src_const = (float) luaL_checknumber(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ imlua_matchsize(L, src_image, dst_image);
+
+ switch (src_image->data_type)
+ {
+ case IM_BYTE:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_BYTE ||
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is byte, destiny image data type can be byte, ushort, int and float only.");
+ break;
+ case IM_USHORT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is ushort, destiny image data type can be ushort, int and float only.");
+ break;
+ case IM_INT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is int, destiny image data type can be int and float only.");
+ break;
+ case IM_FLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is float, destiny image data type can be float only.");
+ break;
+ case IM_CFLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_CFLOAT,
+ 2, "source image is cfloat, destiny image data type can be cfloat only.");
+ break;
+ }
+
+ imProcessArithmeticConstOp(src_image, src_const, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBlendConst
+\*****************************************************************************/
+static int imluaProcessBlendConst (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ float alpha = (float) luaL_checknumber(L, 4);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+
+ imProcessBlendConst(src_image1, src_image2, dst_image, alpha);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBlend
+\*****************************************************************************/
+static int imluaProcessBlend (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *alpha_image = imlua_checkimage(L, 3);
+ imImage *dst_image = imlua_checkimage(L, 4);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+ imlua_matchdatatype(L, src_image1, alpha_image);
+
+ imProcessBlend(src_image1, src_image2, alpha_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSplitComplex
+\*****************************************************************************/
+static int imluaProcessSplitComplex (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image1 = imlua_checkimage(L, 2);
+ imImage *dst_image2 = imlua_checkimage(L, 3);
+ int polar = lua_toboolean(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+ imlua_checkdatatype(L, 2, dst_image1, IM_FLOAT);
+ imlua_checkdatatype(L, 3, dst_image2, IM_FLOAT);
+ imlua_matchcolorspace(L, src_image, dst_image1);
+ imlua_matchcolorspace(L, src_image, dst_image2);
+
+ imProcessSplitComplex(src_image, dst_image1, dst_image2, polar);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMergeComplex
+\*****************************************************************************/
+static int imluaProcessMergeComplex (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int polar = lua_toboolean(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image1, IM_FLOAT);
+ imlua_checkdatatype(L, 2, src_image2, IM_FLOAT);
+ imlua_checkdatatype(L, 3, dst_image, IM_CFLOAT);
+ imlua_matchcolorspace(L, src_image1, src_image2);
+ imlua_matchcolorspace(L, src_image1, dst_image);
+
+ imProcessMergeComplex(src_image1, src_image2, dst_image, polar);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMultipleMean
+\*****************************************************************************/
+static int imluaProcessMultipleMean (lua_State *L)
+{
+ int i, src_image_count;
+ imImage *dst_image;
+ imImage **src_image_list;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+ src_image_count = imlua_getn(L, 1);
+
+ src_image_list = (imImage**)malloc(sizeof(imImage*)*src_image_count);
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ lua_rawgeti(L, 1, i+1);
+ src_image_list[i] = imlua_checkimage(L, -1);
+ }
+
+ dst_image = imlua_checkimage(L, 2);
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ int check = imImageMatchDataType(src_image_list[i], dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+
+ imProcessMultipleMean((const imImage**)src_image_list, src_image_count, dst_image);
+ free(src_image_list);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMultipleStdDev
+\*****************************************************************************/
+static int imluaProcessMultipleStdDev (lua_State *L)
+{
+ int i, src_image_count, check;
+ imImage *dst_image, *mean_image;
+ imImage **src_image_list;
+
+ if (!lua_istable(L, 1))
+ luaL_argerror(L, 1, "must be a table");
+
+ lua_pushstring(L, "table");
+ lua_gettable(L, LUA_GLOBALSINDEX);
+ lua_pushstring(L, "getn");
+ lua_gettable(L, -2);
+ src_image_count = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+
+ src_image_list = (imImage**) malloc(src_image_count * sizeof(imImage*));
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ lua_rawgeti(L, 1, i+1);
+ src_image_list[i] = imlua_checkimage(L, -1);
+ }
+
+ mean_image = imlua_checkimage(L, 2);
+ dst_image = imlua_checkimage(L, 3);
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ check = imImageMatchDataType(src_image_list[i], dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+ check = imImageMatchDataType(mean_image, dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+
+ imProcessMultipleStdDev((const imImage**)src_image_list, src_image_count, mean_image, dst_image);
+ free(src_image_list);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessAutoCovariance
+\*****************************************************************************/
+static int imluaProcessAutoCovariance (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *mean_image = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image, mean_image);
+ imlua_matchcolorspace(L, src_image, dst_image);
+ imlua_checkdatatype(L, 3, dst_image, IM_FLOAT);
+
+ lua_pushboolean(L, imProcessAutoCovariance(src_image, mean_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessMultiplyConj
+\*****************************************************************************/
+static int imluaProcessMultiplyConj (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+
+ imProcessMultiplyConj(src_image1, src_image2, dst_image);
+ return 0;
+}
+
+
+/*****************************************************************************\
+ Additional Image Quantization Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessQuantizeRGBUniform
+\*****************************************************************************/
+static int imluaProcessQuantizeRGBUniform (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int dither = lua_toboolean(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_RGB, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_MAP);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessQuantizeRGBUniform(src_image, dst_image, dither);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessQuantizeGrayUniform
+\*****************************************************************************/
+static int imluaProcessQuantizeGrayUniform (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int grays = luaL_checkint(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checktype(L, 2, dst_image, IM_GRAY, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessQuantizeGrayUniform(src_image, dst_image, grays);
+ return 0;
+}
+
+
+/*****************************************************************************\
+ Histogram Based Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessExpandHistogram
+\*****************************************************************************/
+static int imluaProcessExpandHistogram (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, src_image->color_space == IM_RGB || src_image->color_space == IM_GRAY, 1, "color space can be RGB or Gray only");
+ luaL_argcheck(L, dst_image->color_space == IM_RGB || dst_image->color_space == IM_GRAY, 2, "color space can be RGB or Gray only");
+
+ imProcessExpandHistogram(src_image, dst_image, percent);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessEqualizeHistogram
+\*****************************************************************************/
+static int imluaProcessEqualizeHistogram (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, src_image->color_space == IM_RGB || src_image->color_space == IM_GRAY, 1, "color space can be RGB or Gray only");
+ luaL_argcheck(L, dst_image->color_space == IM_RGB || dst_image->color_space == IM_GRAY, 2, "color space can be RGB or Gray only");
+
+ imProcessEqualizeHistogram(src_image, dst_image);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Color Processing Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessSplitYChroma
+\*****************************************************************************/
+static int imluaProcessSplitYChroma (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *y_image = imlua_checkimage(L, 2);
+ imImage *chroma_image = imlua_checkimage(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_RGB, IM_BYTE);
+ imlua_checktype(L, 2, y_image, IM_GRAY, IM_BYTE);
+ imlua_checktype(L, 3, chroma_image, IM_RGB, IM_BYTE);
+ imlua_matchsize(L, src_image, y_image);
+ imlua_matchsize(L, src_image, chroma_image);
+
+ imProcessSplitYChroma(src_image, y_image, chroma_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSplitHSI
+\*****************************************************************************/
+static int imluaProcessSplitHSI (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *h_image = imlua_checkimage(L, 2);
+ imImage *s_image = imlua_checkimage(L, 3);
+ imImage *i_image = imlua_checkimage(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_RGB);
+ luaL_argcheck(L, src_image->data_type == IM_BYTE || src_image->data_type == IM_FLOAT, 1, "data type can be float or byte only");
+ imlua_checktype(L, 2, h_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 3, s_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 4, i_image, IM_GRAY, IM_FLOAT);
+ imlua_matchsize(L, src_image, h_image);
+ imlua_matchsize(L, src_image, s_image);
+ imlua_matchsize(L, src_image, i_image);
+
+ imProcessSplitHSI(src_image, h_image, s_image, i_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMergeHSI
+\*****************************************************************************/
+static int imluaProcessMergeHSI (lua_State *L)
+{
+ imImage *h_image = imlua_checkimage(L, 1);
+ imImage *s_image = imlua_checkimage(L, 2);
+ imImage *i_image = imlua_checkimage(L, 3);
+ imImage *dst_image = imlua_checkimage(L, 4);
+
+ imlua_checktype(L, 1, h_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 2, s_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 3, i_image, IM_GRAY, IM_FLOAT);
+ imlua_checkcolorspace(L, 4, dst_image, IM_RGB);
+ luaL_argcheck(L, dst_image->data_type == IM_BYTE || dst_image->data_type == IM_FLOAT, 4, "data type can be float or byte only");
+ imlua_matchsize(L, dst_image, h_image);
+ imlua_matchsize(L, dst_image, s_image);
+ imlua_matchsize(L, dst_image, i_image);
+
+ imProcessMergeHSI(h_image, s_image, i_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSplitComponents(src_image, { r, g, b} )
+\*****************************************************************************/
+static int imluaProcessSplitComponents (lua_State *L)
+{
+ int i;
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage **dst_image_list;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ if (imlua_getn(L, 2) != src_image->depth)
+ luaL_error(L, "number of destiny images must match the depth of the source image");
+
+ dst_image_list = (imImage**)malloc(sizeof(imImage*)*src_image->depth);
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ lua_pushnumber(L, i+1);
+ lua_gettable(L, 2);
+ dst_image_list[i] = imlua_checkimage(L, -1);
+ imlua_checkcolorspace(L, 2, dst_image_list[i], IM_GRAY); /* if error here, there will be a memory leak */
+ lua_pop(L, 1);
+ }
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ int check = imImageMatchDataType(src_image, dst_image_list[i]);
+ if (!check) free(dst_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+
+ imProcessSplitComponents(src_image, dst_image_list);
+
+ free(dst_image_list);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMergeComponents({r, g, b}, rgb)
+\*****************************************************************************/
+static int imluaProcessMergeComponents (lua_State *L)
+{
+ int i;
+ imImage** src_image_list;
+ imImage *dst_image;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+ dst_image = imlua_checkimage(L, 2);
+
+ if (imlua_getn(L, 1) != dst_image->depth)
+ luaL_error(L, "number of source images must match the depth of the destination image");
+
+ src_image_list = (imImage**)malloc(sizeof(imImage*)*dst_image->depth);
+
+ for (i = 0; i < dst_image->depth; i++)
+ {
+ lua_pushnumber(L, i+1);
+ lua_gettable(L, 1);
+ src_image_list[i] = imlua_checkimage(L, -1);
+ imlua_checkcolorspace(L, 1, src_image_list[i], IM_GRAY);
+ lua_pop(L, 1);
+ }
+
+ for (i = 0; i < dst_image->depth; i++)
+ {
+ int check = imImageMatchDataType(src_image_list[i], dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+
+ imProcessMergeComponents((const imImage**)src_image_list, dst_image);
+
+ free(src_image_list);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessNormalizeComponents
+\*****************************************************************************/
+static int imluaProcessNormalizeComponents (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkdatatype(L, 2, dst_image, IM_FLOAT);
+ imlua_matchcolorspace(L, src_image, dst_image);
+
+ imProcessNormalizeComponents(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessReplaceColor
+\*****************************************************************************/
+static int imluaProcessReplaceColor (lua_State *L)
+{
+ int src_count, dst_count;
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float *src_color = imlua_toarrayfloat(L, 3, &src_count, 1);
+ float *dst_color = imlua_toarrayfloat(L, 4, &dst_count, 1);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, src_count == src_image->depth, 3, "the colors must have the same number of components of the images");
+ luaL_argcheck(L, dst_count == src_image->depth, 4, "the colors must have the same number of components of the images");
+
+ imProcessReplaceColor(src_image, dst_image, src_color, dst_color);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Logical Arithmetic Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessBitwiseOp
+\*****************************************************************************/
+static int imluaProcessBitwiseOp (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ luaL_argcheck(L, (src_image1->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+
+ imProcessBitwiseOp(src_image1, src_image2, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBitwiseNot
+\*****************************************************************************/
+static int imluaProcessBitwiseNot (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBitwiseNot(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBitMask(src_image, dst_image, mask, op)
+\*****************************************************************************/
+static int imluaProcessBitMask (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ unsigned char mask = imlua_checkmask(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBitMask(src_image, dst_image, mask, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBitPlane(src_image, dst_image, plane, reset)
+\*****************************************************************************/
+static int imluaProcessBitPlane (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int plane = luaL_checkint(L, 3);
+ int reset = lua_toboolean(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBitPlane(src_image, dst_image, plane, reset);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Synthetic Image Render
+\*****************************************************************************/
+
+/* NOTE: This breaks on multithread */
+static lua_State *g_renderState = NULL;
+int g_paramCount = 0;
+
+static float imluaRenderFunc (int x, int y, int d, float *param)
+{
+ lua_State *L = g_renderState;
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_pushvalue(L, 2);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, d);
+ imlua_newarrayfloat(L, param, g_paramCount, 1);
+
+ lua_call(L, 4, 1);
+
+ return (float) luaL_checknumber(L, -1);
+}
+
+/*****************************************************************************\
+ im.ProcessRenderOp(image, function, name, param, plus)
+\*****************************************************************************/
+static int imluaProcessRenderOp (lua_State *L)
+{
+ int count;
+
+ imImage *image = imlua_checkimage(L, 1);
+ const char *render_name = luaL_checkstring(L, 3);
+ float *param = imlua_toarrayfloat(L, 4, &count, 1);
+ int plus = luaL_checkint(L, 5);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+
+ g_renderState = L;
+ g_paramCount = count;
+ lua_pushboolean(L, imProcessRenderOp(image, imluaRenderFunc, (char*) render_name, param, plus));
+ return 1;
+}
+
+static float imluaRenderCondFunc (int x, int y, int d, int *cond, float *param)
+{
+ lua_State *L = g_renderState;
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_pushvalue(L, 2);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, d);
+ imlua_newarrayfloat(L, param, g_paramCount, 1);
+
+ lua_call(L, 4, 2);
+
+ *cond = lua_toboolean(L, -1);
+ return (float) luaL_checknumber(L, -2);
+}
+
+/*****************************************************************************\
+ im.ProcessRenderCondOp(image, function, name, param)
+\*****************************************************************************/
+static int imluaProcessRenderCondOp (lua_State *L)
+{
+ int count;
+
+ imImage *image = imlua_checkimage(L, 1);
+ const char *render_name = luaL_checkstring(L, 3);
+ float *param = imlua_toarrayfloat(L, 4, &count, 1);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+
+ g_renderState = L;
+ g_paramCount = count;
+ lua_pushboolean(L, imProcessRenderCondOp(image, imluaRenderCondFunc, (char*) render_name, param));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderAddSpeckleNoise
+\*****************************************************************************/
+static int imluaProcessRenderAddSpeckleNoise (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRenderAddSpeckleNoise(src_image, dst_image, percent));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderAddGaussianNoise
+\*****************************************************************************/
+static int imluaProcessRenderAddGaussianNoise (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float mean = (float) luaL_checknumber(L, 3);
+ float stddev = (float) luaL_checknumber(L, 4);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRenderAddGaussianNoise(src_image, dst_image, mean, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderAddUniformNoise
+\*****************************************************************************/
+static int imluaProcessRenderAddUniformNoise (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float mean = (float) luaL_checknumber(L, 3);
+ float stddev = (float) luaL_checknumber(L, 4);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRenderAddUniformNoise(src_image, dst_image, mean, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderRandomNoise
+\*****************************************************************************/
+static int imluaProcessRenderRandomNoise (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ imlua_checknotcfloat(L, image, 1);
+ lua_pushboolean(L, imProcessRenderRandomNoise(image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderConstant(image, [count])
+\*****************************************************************************/
+static int imluaProcessRenderConstant (lua_State *L)
+{
+ int i;
+ float *value = NULL;
+
+ imImage *image = imlua_checkimage(L, 1);
+ int count = image->depth;
+
+ imlua_checknotcfloat(L, image, 1);
+
+ if (lua_istable(L, 2))
+ {
+ value = (float*) malloc (sizeof(float) * count);
+
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 2, i+1);
+ value[i] = (float) lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+
+ lua_pushboolean(L, imProcessRenderConstant(image, value));
+
+ if (value)
+ free(value);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderWheel
+\*****************************************************************************/
+static int imluaProcessRenderWheel (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int int_radius = luaL_checkint(L, 2);
+ int ext_radius = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderWheel(image, int_radius, ext_radius));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderCone
+\*****************************************************************************/
+static int imluaProcessRenderCone (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int radius = luaL_checkint(L, 2);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderCone(image, radius));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderTent
+\*****************************************************************************/
+static int imluaProcessRenderTent (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderTent(image, width, height));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderRamp
+\*****************************************************************************/
+static int imluaProcessRenderRamp (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int start = luaL_checkint(L, 2);
+ int end = luaL_checkint(L, 3);
+ int dir = luaL_checkint(L, 4);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderRamp(image, start, end, dir));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderBox
+\*****************************************************************************/
+static int imluaProcessRenderBox (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderBox(image, width, height));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderSinc
+\*****************************************************************************/
+static int imluaProcessRenderSinc (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float xperiod = (float) luaL_checknumber(L, 2);
+ float yperiod = (float) luaL_checknumber(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderSinc(image, xperiod, yperiod));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderGaussian
+\*****************************************************************************/
+static int imluaProcessRenderGaussian (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float stddev = (float) luaL_checknumber(L, 2);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderGaussian(image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderLapOfGaussian
+\*****************************************************************************/
+static int imluaProcessRenderLapOfGaussian (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float stddev = (float) luaL_checknumber(L, 2);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderLapOfGaussian(image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderCosine
+\*****************************************************************************/
+static int imluaProcessRenderCosine (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float xperiod = (float) luaL_checknumber(L, 2);
+ float yperiod = (float) luaL_checknumber(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderCosine(image, xperiod, yperiod));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderGrid
+\*****************************************************************************/
+static int imluaProcessRenderGrid (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int x_space = luaL_checkint(L, 2);
+ int y_space = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderGrid(image, x_space, y_space));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderChessboard
+\*****************************************************************************/
+static int imluaProcessRenderChessboard (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int x_space = luaL_checkint(L, 2);
+ int y_space = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderChessboard(image, x_space, y_space));
+ return 1;
+}
+
+
+
+/*****************************************************************************\
+ Tone Gamut Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessToneGamut
+\*****************************************************************************/
+static int imluaProcessToneGamut (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int op = luaL_checkint(L, 3);
+ float *param = NULL;
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ param = imlua_toarrayfloat(L, 4, NULL, 1);
+
+ imProcessToneGamut(src_image, dst_image, op, param);
+
+ if (param)
+ free(param);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessUnNormalize
+\*****************************************************************************/
+static int imluaProcessUnNormalize (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_FLOAT);
+ imlua_checkdatatype(L, 2, dst_image, IM_BYTE);
+ imlua_matchcolorspace(L, src_image, dst_image);
+
+ imProcessUnNormalize(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessDirectConv
+\*****************************************************************************/
+static int imluaProcessDirectConv (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L,
+ src_image->data_type == IM_USHORT ||
+ src_image->data_type == IM_INT ||
+ src_image->data_type == IM_FLOAT,
+ 1, "data type can be ushort, int or float only");
+ imlua_checkdatatype(L, 2, dst_image, IM_BYTE);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessDirectConv(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessNegative
+\*****************************************************************************/
+static int imluaProcessNegative (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessNegative(src_image, dst_image);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Threshold Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessRangeContrastThreshold
+\*****************************************************************************/
+static int imluaProcessRangeContrastThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int min_range = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRangeContrastThreshold(src_image, dst_image, kernel_size, min_range));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessLocalMaxThreshold
+\*****************************************************************************/
+static int imluaProcessLocalMaxThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int min_thres = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessLocalMaxThreshold(src_image, dst_image, kernel_size, min_thres));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessThreshold
+\*****************************************************************************/
+static int imluaProcessThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int level = luaL_checkint(L, 3);
+ int value = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessThreshold(src_image, dst_image, level, value);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessThresholdByDiff
+\*****************************************************************************/
+static int imluaProcessThresholdByDiff (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+
+ imlua_checktype(L, 1, src_image1, IM_GRAY, IM_BYTE);
+ imlua_match(L, src_image1, src_image2);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image1, dst_image);
+
+ imProcessThresholdByDiff(src_image1, src_image2, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessHysteresisThreshold
+\*****************************************************************************/
+static int imluaProcessHysteresisThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int low_thres = luaL_checkint(L, 3);
+ int high_thres = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessHysteresisThreshold(src_image, dst_image, low_thres, high_thres);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessHysteresisThresEstimate
+\*****************************************************************************/
+static int imluaProcessHysteresisThresEstimate (lua_State *L)
+{
+ int low_thres, high_thres;
+
+ imImage *src_image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+
+ imProcessHysteresisThresEstimate(src_image, &low_thres, &high_thres);
+ lua_pushnumber(L, low_thres);
+ lua_pushnumber(L, high_thres);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ im.ProcessUniformErrThreshold
+\*****************************************************************************/
+static int imluaProcessUniformErrThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessUniformErrThreshold(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessDifusionErrThreshold
+\*****************************************************************************/
+static int imluaProcessDifusionErrThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int level = luaL_checkint(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_checkdatatype(L, 2, dst_image, IM_BYTE);
+ imlua_matchcheck(L, src_image->depth == dst_image->depth, "images must have the same depth");
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessDifusionErrThreshold(src_image, dst_image, level);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessPercentThreshold
+\*****************************************************************************/
+static int imluaProcessPercentThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessPercentThreshold(src_image, dst_image, percent));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessOtsuThreshold
+\*****************************************************************************/
+static int imluaProcessOtsuThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushnumber(L, imProcessOtsuThreshold(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessMinMaxThreshold
+\*****************************************************************************/
+static int imluaProcessMinMaxThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_GRAY);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessMinMaxThreshold(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessLocalMaxThresEstimate
+\*****************************************************************************/
+static int imluaProcessLocalMaxThresEstimate (lua_State *L)
+{
+ int thres;
+ imImage *image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, image, IM_BYTE);
+
+ imProcessLocalMaxThresEstimate(image, &thres);
+
+ lua_pushnumber(L, thres);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSliceThreshold
+\*****************************************************************************/
+static int imluaProcessSliceThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ int start_level = luaL_checkint(L, 3);
+ int end_level = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_GRAY);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessSliceThreshold(src_image, dst_image, start_level, end_level);
+ return 0;
+}
+
+
+/*****************************************************************************\
+ Special Effects
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessPixelate
+\*****************************************************************************/
+static int imluaProcessPixelate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int box_size = luaL_checkint(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessPixelate(src_image, dst_image, box_size);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessPosterize
+\*****************************************************************************/
+static int imluaProcessPosterize (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int level = luaL_checkint(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (level >= 1 && level <= 7), 3, "invalid level, must be >=1 and <=7");
+
+ imProcessPosterize(src_image, dst_image, level);
+ return 0;
+}
+
+
+
+static const luaL_reg improcess_lib[] = {
+ {"CalcRMSError", imluaCalcRMSError},
+ {"CalcSNR", imluaCalcSNR},
+ {"CalcCountColors", imluaCalcCountColors},
+ {"CalcHistogram", imluaCalcHistogram},
+ /*{"CalcUShortHistogram", imluaCalcUShortHistogram}, done by imluaCalcHistogram */
+ {"CalcGrayHistogram", imluaCalcGrayHistogram},
+ {"CalcImageStatistics", imluaCalcImageStatistics},
+ {"CalcHistogramStatistics", imluaCalcHistogramStatistics},
+ {"CalcHistoImageStatistics", imluaCalcHistoImageStatistics},
+
+ {"AnalyzeFindRegions", imluaAnalyzeFindRegions},
+ {"AnalyzeMeasureArea", imluaAnalyzeMeasureArea},
+ {"AnalyzeMeasurePerimArea", imluaAnalyzeMeasurePerimArea},
+ {"AnalyzeMeasureCentroid", imluaAnalyzeMeasureCentroid},
+ {"AnalyzeMeasurePrincipalAxis", imluaAnalyzeMeasurePrincipalAxis},
+ {"AnalyzeMeasurePerimeter", imluaAnalyzeMeasurePerimeter},
+ {"AnalyzeMeasureHoles", imluaAnalyzeMeasureHoles},
+
+ {"ProcessPerimeterLine", imluaProcessPerimeterLine},
+ {"ProcessRemoveByArea", imluaProcessRemoveByArea},
+ {"ProcessFillHoles", imluaProcessFillHoles},
+
+ {"ProcessHoughLines", imluaProcessHoughLines},
+ {"ProcessHoughLinesDraw", imluaProcessHoughLinesDraw},
+ {"ProcessDistanceTransform", imluaProcessDistanceTransform},
+ {"ProcessRegionalMaximum", imluaProcessRegionalMaximum},
+
+ {"ProcessReduce", imluaProcessReduce},
+ {"ProcessResize", imluaProcessResize},
+ {"ProcessReduceBy4", imluaProcessReduceBy4},
+ {"ProcessCrop", imluaProcessCrop},
+ {"ProcessAddMargins", imluaProcessAddMargins},
+ {"ProcessInsert", imluaProcessInsert},
+
+ {"ProcessCalcRotateSize", imluaProcessCalcRotateSize},
+ {"ProcessRotate", imluaProcessRotate},
+ {"ProcessRotateRef", imluaProcessRotateRef},
+ {"ProcessRotate90", imluaProcessRotate90},
+ {"ProcessRotate180", imluaProcessRotate180},
+ {"ProcessMirror", imluaProcessMirror},
+ {"ProcessFlip", imluaProcessFlip},
+ {"ProcessRadial", imluaProcessRadial},
+ {"ProcessSwirl", imluaProcessSwirl},
+ {"ProcessInterlaceSplit", imluaProcessInterlaceSplit},
+
+ {"ProcessGrayMorphConvolve", imluaProcessGrayMorphConvolve},
+ {"ProcessGrayMorphErode", imluaProcessGrayMorphErode},
+ {"ProcessGrayMorphDilate", imluaProcessGrayMorphDilate},
+ {"ProcessGrayMorphOpen", imluaProcessGrayMorphOpen},
+ {"ProcessGrayMorphClose", imluaProcessGrayMorphClose},
+ {"ProcessGrayMorphTopHat", imluaProcessGrayMorphTopHat},
+ {"ProcessGrayMorphWell", imluaProcessGrayMorphWell},
+ {"ProcessGrayMorphGradient", imluaProcessGrayMorphGradient},
+
+ {"ProcessBinMorphConvolve", imluaProcessBinMorphConvolve},
+ {"ProcessBinMorphErode", imluaProcessBinMorphErode},
+ {"ProcessBinMorphDilate", imluaProcessBinMorphDilate},
+ {"ProcessBinMorphOpen", imluaProcessBinMorphOpen},
+ {"ProcessBinMorphClose", imluaProcessBinMorphClose},
+ {"ProcessBinMorphOutline", imluaProcessBinMorphOutline},
+ {"ProcessBinMorphThin", imluaProcessBinMorphThin},
+
+ {"ProcessMedianConvolve", imluaProcessMedianConvolve},
+ {"ProcessRangeConvolve", imluaProcessRangeConvolve},
+ {"ProcessRankClosestConvolve", imluaProcessRankClosestConvolve},
+ {"ProcessRankMaxConvolve", imluaProcessRankMaxConvolve},
+ {"ProcessRankMinConvolve", imluaProcessRankMinConvolve},
+
+ {"ProcessConvolve", imluaProcessConvolve},
+ {"ProcessConvolveDual", imluaProcessConvolveDual},
+ {"ProcessConvolveRep", imluaProcessConvolveRep},
+ {"ProcessConvolveSep", imluaProcessConvolveSep},
+ {"ProcessCompassConvolve", imluaProcessCompassConvolve},
+ {"ProcessRotateKernel", imluaProcessRotateKernel},
+ {"ProcessDiffOfGaussianConvolve", imluaProcessDiffOfGaussianConvolve},
+ {"ProcessLapOfGaussianConvolve", imluaProcessLapOfGaussianConvolve},
+ {"ProcessMeanConvolve", imluaProcessMeanConvolve},
+ {"ProcessBarlettConvolve", imluaProcessBarlettConvolve},
+ {"ProcessGaussianConvolve", imluaProcessGaussianConvolve},
+ {"ProcessSobelConvolve", imluaProcessSobelConvolve},
+ {"ProcessPrewittConvolve", imluaProcessPrewittConvolve},
+ {"ProcessSplineEdgeConvolve", imluaProcessSplineEdgeConvolve},
+ {"ProcessZeroCrossing", imluaProcessZeroCrossing},
+ {"ProcessCanny", imluaProcessCanny},
+ {"ProcessUnsharp", imluaProcessUnsharp},
+ {"ProcessSharp", imluaProcessSharp},
+ {"ProcessSharpKernel", imluaProcessSharpKernel},
+ {"GaussianKernelSize2StdDev", imluaGaussianKernelSize2StdDev},
+ {"GaussianStdDev2KernelSize", imluaGaussianStdDev2KernelSize},
+
+ {"ProcessUnArithmeticOp", imluaProcessUnArithmeticOp},
+ {"ProcessArithmeticOp", imluaProcessArithmeticOp},
+ {"ProcessArithmeticConstOp", imluaProcessArithmeticConstOp},
+ {"ProcessBlendConst", imluaProcessBlendConst},
+ {"ProcessBlend", imluaProcessBlend},
+ {"ProcessSplitComplex", imluaProcessSplitComplex},
+ {"ProcessMergeComplex", imluaProcessMergeComplex},
+ {"ProcessMultipleMean", imluaProcessMultipleMean},
+ {"ProcessMultipleStdDev", imluaProcessMultipleStdDev},
+ {"ProcessAutoCovariance", imluaProcessAutoCovariance},
+ {"ProcessMultiplyConj", imluaProcessMultiplyConj},
+
+ {"ProcessQuantizeRGBUniform", imluaProcessQuantizeRGBUniform},
+ {"ProcessQuantizeGrayUniform", imluaProcessQuantizeGrayUniform},
+
+ {"ProcessExpandHistogram", imluaProcessExpandHistogram},
+ {"ProcessEqualizeHistogram", imluaProcessEqualizeHistogram},
+
+ {"ProcessSplitYChroma", imluaProcessSplitYChroma},
+ {"ProcessSplitHSI", imluaProcessSplitHSI},
+ {"ProcessMergeHSI", imluaProcessMergeHSI},
+ {"ProcessSplitComponents", imluaProcessSplitComponents},
+ {"ProcessMergeComponents", imluaProcessMergeComponents},
+ {"ProcessNormalizeComponents", imluaProcessNormalizeComponents},
+ {"ProcessReplaceColor", imluaProcessReplaceColor},
+
+ {"ProcessBitwiseOp", imluaProcessBitwiseOp},
+ {"ProcessBitwiseNot", imluaProcessBitwiseNot},
+ {"ProcessBitMask", imluaProcessBitMask},
+ {"ProcessBitPlane", imluaProcessBitPlane},
+
+ {"ProcessRenderOp", imluaProcessRenderOp},
+ {"ProcessRenderCondOp", imluaProcessRenderCondOp},
+ {"ProcessRenderAddSpeckleNoise", imluaProcessRenderAddSpeckleNoise},
+ {"ProcessRenderAddGaussianNoise", imluaProcessRenderAddGaussianNoise},
+ {"ProcessRenderAddUniformNoise", imluaProcessRenderAddUniformNoise},
+ {"ProcessRenderRandomNoise", imluaProcessRenderRandomNoise},
+ {"ProcessRenderConstant", imluaProcessRenderConstant},
+ {"ProcessRenderWheel", imluaProcessRenderWheel},
+ {"ProcessRenderCone", imluaProcessRenderCone},
+ {"ProcessRenderTent", imluaProcessRenderTent},
+ {"ProcessRenderRamp", imluaProcessRenderRamp},
+ {"ProcessRenderBox", imluaProcessRenderBox},
+ {"ProcessRenderSinc", imluaProcessRenderSinc},
+ {"ProcessRenderGaussian", imluaProcessRenderGaussian},
+ {"ProcessRenderLapOfGaussian", imluaProcessRenderLapOfGaussian},
+ {"ProcessRenderCosine", imluaProcessRenderCosine},
+ {"ProcessRenderGrid", imluaProcessRenderGrid},
+ {"ProcessRenderChessboard", imluaProcessRenderChessboard},
+
+ {"ProcessToneGamut", imluaProcessToneGamut},
+ {"ProcessUnNormalize", imluaProcessUnNormalize},
+ {"ProcessDirectConv", imluaProcessDirectConv},
+ {"ProcessNegative", imluaProcessNegative},
+
+ {"ProcessRangeContrastThreshold", imluaProcessRangeContrastThreshold},
+ {"ProcessLocalMaxThreshold", imluaProcessLocalMaxThreshold},
+ {"ProcessThreshold", imluaProcessThreshold},
+ {"ProcessThresholdByDiff", imluaProcessThresholdByDiff},
+ {"ProcessHysteresisThreshold", imluaProcessHysteresisThreshold},
+ {"ProcessHysteresisThresEstimate", imluaProcessHysteresisThresEstimate},
+ {"ProcessUniformErrThreshold", imluaProcessUniformErrThreshold},
+ {"ProcessDifusionErrThreshold", imluaProcessDifusionErrThreshold},
+ {"ProcessPercentThreshold", imluaProcessPercentThreshold},
+ {"ProcessOtsuThreshold", imluaProcessOtsuThreshold},
+ {"ProcessMinMaxThreshold", imluaProcessMinMaxThreshold},
+ {"ProcessLocalMaxThresEstimate", imluaProcessLocalMaxThresEstimate},
+ {"ProcessSliceThreshold", imluaProcessSliceThreshold},
+
+ {"ProcessPixelate", imluaProcessPixelate},
+ {"ProcessPosterize", imluaProcessPosterize},
+
+ {NULL, NULL}
+};
+
+/*****************************************************************************\
+ Constants
+\*****************************************************************************/
+static const imlua_constant im_process_constants[] = {
+
+ { "UN_EQL", IM_UN_EQL, NULL },
+ { "UN_ABS", IM_UN_ABS, NULL },
+ { "UN_LESS", IM_UN_LESS, NULL },
+ { "UN_INV", IM_UN_INV, NULL },
+ { "UN_SQR", IM_UN_SQR, NULL },
+ { "UN_SQRT", IM_UN_SQRT, NULL },
+ { "UN_LOG", IM_UN_LOG, NULL },
+ { "UN_EXP", IM_UN_EXP, NULL },
+ { "UN_SIN", IM_UN_SIN, NULL },
+ { "UN_COS", IM_UN_COS, NULL },
+ { "UN_CONJ", IM_UN_CONJ, NULL },
+ { "UN_CPXNORM", IM_UN_CPXNORM, NULL },
+
+ { "BIN_ADD", IM_BIN_ADD, NULL },
+ { "BIN_SUB", IM_BIN_SUB, NULL },
+ { "BIN_MUL", IM_BIN_MUL, NULL },
+ { "BIN_DIV", IM_BIN_DIV, NULL },
+ { "BIN_DIFF", IM_BIN_DIFF, NULL },
+ { "BIN_POW", IM_BIN_POW, NULL },
+ { "BIN_MIN", IM_BIN_MIN, NULL },
+ { "BIN_MAX", IM_BIN_MAX, NULL },
+
+ { "BIT_AND", IM_BIT_AND, NULL },
+ { "BIT_OR", IM_BIT_OR, NULL },
+ { "BIT_XOR", IM_BIT_XOR, NULL },
+
+ { "GAMUT_NORMALIZE", IM_GAMUT_NORMALIZE, NULL },
+ { "GAMUT_POW", IM_GAMUT_POW, NULL },
+ { "GAMUT_LOG", IM_GAMUT_LOG, NULL },
+ { "GAMUT_EXP", IM_GAMUT_EXP, NULL },
+ { "GAMUT_INVERT", IM_GAMUT_INVERT, NULL },
+ { "GAMUT_ZEROSTART", IM_GAMUT_ZEROSTART, NULL },
+ { "GAMUT_SOLARIZE", IM_GAMUT_SOLARIZE, NULL },
+ { "GAMUT_SLICE", IM_GAMUT_SLICE, NULL },
+ { "GAMUT_EXPAND", IM_GAMUT_EXPAND, NULL },
+ { "GAMUT_CROP", IM_GAMUT_CROP, NULL },
+ { "GAMUT_BRIGHTCONT", IM_GAMUT_BRIGHTCONT, NULL },
+
+ { NULL, -1, NULL },
+};
+
+/* from imlua_kernel.c */
+void imlua_open_kernel(lua_State *L);
+
+int imlua_open_process(lua_State *L)
+{
+ luaL_register(L, "im", improcess_lib); /* leave "im" table at the top of the stack */
+ imlua_regconstants(L, im_process_constants);
+#ifdef TEC_BIGENDIAN
+#ifdef TEC_64
+#include "loh/im_process_be64.loh"
+#else
+#include "loh/im_process_be32.loh"
+#endif
+#else
+#ifdef TEC_64
+#ifdef WIN64
+#include "loh/im_process_le64w.loh"
+#else
+#include "loh/im_process_le64.loh"
+#endif
+#else
+#include "loh/im_process.loh"
+#endif
+#endif
+ imlua_open_kernel(L);
+ return 1;
+}
+
+int luaopen_imlua_process(lua_State *L)
+{
+ return imlua_open_process(L);
+}
+
+int luaopen_imlua_process51(lua_State *L)
+{
+ return imlua_open_process(L);
+}
diff --git a/im/src/lua5/imlua_process.def b/im/src/lua5/imlua_process.def
new file mode 100755
index 0000000..2b77e77
--- /dev/null
+++ b/im/src/lua5/imlua_process.def
@@ -0,0 +1,4 @@
+EXPORTS
+ imlua_open_process
+ luaopen_imlua_process
+ luaopen_imlua_process51 \ No newline at end of file
diff --git a/im/src/lua5/imlua_util.c b/im/src/lua5/imlua_util.c
new file mode 100755
index 0000000..69cfb19
--- /dev/null
+++ b/im/src/lua5/imlua_util.c
@@ -0,0 +1,279 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_util.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_util.h"
+#include "im_image.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+
+/*****************************************************************************\
+ im.ImageDataSize(width, height, color_mode, data_type)
+\*****************************************************************************/
+static int imluaImageDataSize (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int height = luaL_checkint(L, 2);
+ int color_mode = luaL_checkint(L, 3);
+ int data_type = luaL_checkint(L, 4);
+
+ lua_pushnumber(L, imImageDataSize(width, height, color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ImageLineSize(width, color_mode, data_type)
+\*****************************************************************************/
+static int imluaImageLineSize (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int color_mode = luaL_checkint(L, 2);
+ int data_type = luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imImageLineSize(width, color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ImageLineCount(width, color_mode)
+\*****************************************************************************/
+static int imluaImageLineCount (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int color_mode = luaL_checkint(L, 2);
+
+ lua_pushnumber(L, imImageLineCount(width, color_mode));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ImageCheckFormat(width, color_mode)
+\*****************************************************************************/
+static int imluaImageCheckFormat (lua_State *L)
+{
+ int color_mode = luaL_checkint(L, 1);
+ int data_type = luaL_checkint(L, 2);
+
+ lua_pushboolean(L, imImageCheckFormat(color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeSpaceName(color_mode)
+\*****************************************************************************/
+static int imluaColorModeSpaceName (lua_State *L)
+{
+ lua_pushstring(L, imColorModeSpaceName(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeDepth(color_mode)
+\*****************************************************************************/
+static int imluaColorModeDepth (lua_State *L)
+{
+ lua_pushnumber(L, imColorModeDepth(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ColorModeSpace(color_mode)
+\*****************************************************************************/
+static int imluaColorModeSpace (lua_State *L)
+{
+ lua_pushnumber(L, imColorModeSpace(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeHasAlpha(color_mode)
+\*****************************************************************************/
+static int imluaColorModeMatch (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeMatch(luaL_checkint(L, 1), luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeHasAlpha(color_mode)
+\*****************************************************************************/
+static int imluaColorModeHasAlpha (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeHasAlpha(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeIsPacked(color_mode)
+\*****************************************************************************/
+static int imluaColorModeIsPacked (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeIsPacked(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeIsTopDown(color_mode)
+\*****************************************************************************/
+static int imluaColorModeIsTopDown (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeIsTopDown(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeToBitmap(color_mode)
+\*****************************************************************************/
+static int imluaColorModeToBitmap (lua_State *L)
+{
+ lua_pushnumber(L, imColorModeToBitmap(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeIsBitmap
+\*****************************************************************************/
+static int imluaColorModeIsBitmap (lua_State *L)
+{
+ int color_mode = luaL_checkint(L, 1);
+ int data_type = luaL_checkint(L, 2);
+
+ lua_pushboolean(L, imColorModeIsBitmap(color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeSize(data_type)
+\*****************************************************************************/
+static int imluaDataTypeSize (lua_State *L)
+{
+ lua_pushnumber(L, imDataTypeSize(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeName(data_type)
+\*****************************************************************************/
+static int imluaDataTypeName (lua_State *L)
+{
+ lua_pushstring(L, imDataTypeName(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeIntMax(data_type)
+\*****************************************************************************/
+static int imluaDataTypeIntMax(lua_State *L)
+{
+ lua_pushnumber(L, imDataTypeIntMax(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeIntMin(data_type)
+\*****************************************************************************/
+static int imluaDataTypeIntMin(lua_State *L)
+{
+ lua_pushnumber(L, imDataTypeIntMin(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/***************************************************************************\
+* Creates a color as a light userdata. The color value is *
+* placed in the (void *) value. Not beautiful, but works best. *
+* im.ColorEncode(r, g, b: number) -> (c: color) *
+\***************************************************************************/
+static int imlua_colorencode(lua_State *L)
+{
+ int red_f, green_f, blue_f;
+ unsigned char red_i, green_i, blue_i;
+ long int color_i;
+
+ red_f = luaL_checkint(L, 1);
+ green_f = luaL_checkint(L, 2);
+ blue_f = luaL_checkint(L, 3);
+
+ if (red_f < 0 || red_f > 255)
+ luaL_argerror(L, 1, "color components values should be in range [0, 255]");
+ if (green_f < 0 || green_f > 255)
+ luaL_argerror(L, 2, "color components values should be in range [0, 255]");
+ if (blue_f < 0 || blue_f > 255)
+ luaL_argerror(L, 3, "color components values should be in range [0, 255]");
+
+ red_i = (unsigned char) (red_f);
+ green_i = (unsigned char) (green_f);
+ blue_i = (unsigned char) (blue_f);
+
+ color_i = imColorEncode(red_i, green_i, blue_i);
+ lua_pushlightuserdata(L, (void *)color_i);
+
+ return 1;
+}
+
+/***************************************************************************\
+* Decodes a color previously created. *
+* im.ColorDecode(c: color) -> (r, g, b: number) *
+\***************************************************************************/
+static int imlua_colordecode(lua_State *L)
+{
+ long int color_i;
+ unsigned char red_i, green_i, blue_i;
+
+ if (!lua_islightuserdata(L, 1))
+ luaL_argerror(L, 1, "color must be a light user data");
+
+ color_i = (long int) lua_touserdata(L,1);
+
+ imColorDecode(&red_i, &green_i, &blue_i, color_i);
+ lua_pushnumber(L, red_i);
+ lua_pushnumber(L, green_i);
+ lua_pushnumber(L, blue_i);
+
+ return 3;
+}
+
+static const luaL_reg imutil_lib[] = {
+ {"ImageDataSize", imluaImageDataSize},
+ {"ImageLineSize", imluaImageLineSize},
+ {"ImageLineCount", imluaImageLineCount},
+ {"ImageCheckFormat", imluaImageCheckFormat},
+
+ {"ColorModeSpace", imluaColorModeSpace},
+ {"ColorModeSpaceName", imluaColorModeSpaceName},
+ {"ColorModeDepth", imluaColorModeDepth},
+
+ {"ColorModeToBitmap", imluaColorModeToBitmap},
+ {"ColorModeIsBitmap", imluaColorModeIsBitmap},
+ {"ColorModeMatch", imluaColorModeMatch},
+ {"ColorModeHasAlpha", imluaColorModeHasAlpha},
+ {"ColorModeIsPacked", imluaColorModeIsPacked},
+ {"ColorModeIsTopDown", imluaColorModeIsTopDown},
+
+ {"DataTypeSize", imluaDataTypeSize},
+ {"DataTypeName", imluaDataTypeName},
+ {"DataTypeIntMax", imluaDataTypeIntMax},
+ {"DataTypeIntMin", imluaDataTypeIntMin},
+
+ {"ColorEncode", imlua_colorencode},
+ {"ColorDecode", imlua_colordecode},
+
+ {NULL, NULL}
+};
+
+void imlua_open_util(lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ luaL_register(L, NULL, imutil_lib);
+}
diff --git a/im/src/lua5/imlua_wmv.c b/im/src/lua5/imlua_wmv.c
new file mode 100755
index 0000000..7f61030
--- /dev/null
+++ b/im/src/lua5/imlua_wmv.c
@@ -0,0 +1,44 @@
+/** \file
+ * \brief wmv format Lua 5 Binding
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "im_format_wmv.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+
+static int imlua_FormatRegisterWMV(lua_State *L)
+{
+ (void)L;
+ imFormatRegisterWMV();
+ return 0;
+}
+
+static const struct luaL_reg imlib[] = {
+ {"FormatRegisterWMV", imlua_FormatRegisterWMV},
+ {NULL, NULL},
+};
+
+
+static int imlua_wmv_open (lua_State *L)
+{
+ imFormatRegisterWMV();
+ luaL_register(L, "im", imlib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_wmv(lua_State* L)
+{
+ return imlua_wmv_open(L);
+}
+
+int luaopen_imlua_wmv51(lua_State* L)
+{
+ return imlua_wmv_open(L);
+}
diff --git a/im/src/lua5/imlua_wmv.def b/im/src/lua5/imlua_wmv.def
new file mode 100755
index 0000000..0c05563
--- /dev/null
+++ b/im/src/lua5/imlua_wmv.def
@@ -0,0 +1,4 @@
+EXPORTS
+ luaopen_imlua_wmv
+ luaopen_imlua_wmv51
+ \ No newline at end of file
diff --git a/im/src/lua5/loh/im_convert.loh b/im/src/lua5/loh/im_convert.loh
new file mode 100644
index 0000000..7d4b03f
--- /dev/null
+++ b/im/src/lua5/loh/im_convert.loh
@@ -0,0 +1,87 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_convert.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_convert.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 4, 4, 8, 0, 21, 0, 0, 0, 64,108,117, 97,
+ 53, 47,105,109, 95, 99,111,110,118,101,114,116, 46,108,117, 97, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 5, 0, 0, 0,100, 0, 0,
+ 0, 9, 64,128,128, 5, 0, 0, 0,100, 64, 0, 0, 9, 64, 0,129, 5, 0, 0,
+ 0,100,128, 0, 0, 9, 64,128,129, 30, 0,128, 0, 4, 0, 0, 0, 4, 3, 0,
+ 0, 0,105,109, 0, 4, 19, 0, 0, 0, 67,111,110,118,101,114,116, 68, 97,116,
+ 97, 84,121,112,101, 78,101,119, 0, 4, 21, 0, 0, 0, 67,111,110,118,101,114,
+116, 67,111,108,111,114, 83,112, 97, 99,101, 78,101,119, 0, 4, 19, 0, 0, 0,
+ 67,111,110,118,101,114,116, 84,111, 66,105,116,109, 97,112, 78,101,119, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 6, 0, 14, 18,
+ 0, 0, 0,133, 1, 0, 0,134, 65, 64, 3,192, 1, 0, 0, 3, 2, 0, 5,192,
+ 2,128, 0,156,129, 0, 3,197, 1, 0, 0,198,129,192, 3, 0, 2, 0, 0, 64,
+ 2, 0, 3,128, 2, 0, 1,192, 2,128, 1, 0, 3, 0, 2, 64, 3,128, 2,220,
+129,128, 3, 0, 2, 0, 3,222, 1,128, 1, 30, 0,128, 0, 3, 0, 0, 0, 4,
+ 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 4, 16, 0, 0, 0, 67,111,110,118,101,114,
+116, 68, 97,116, 97, 84,121,112,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 3, 0,
+ 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0,
+ 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0,
+100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 9, 0,
+ 0, 0, 99,112,120, 50,114,101, 97,108, 0, 0, 0, 0, 0, 17, 0, 0, 0, 6,
+ 0, 0, 0,103, 97,109,109, 97, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0,
+ 0, 97, 98,115,115,111,108,117,116,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10,
+ 0, 0, 0, 99, 97,115,116, 95,109,111,100,101, 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 6, 0, 0, 0, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, 0,
+ 3, 0, 8, 18, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 67,
+ 1, 0, 3,192, 1,128, 0,220,128,128, 2,154, 0, 0, 0, 22, 64, 0,128, 11,
+129,192, 1, 28, 65, 0, 1, 5, 1, 0, 0, 6,193, 64, 2, 64, 1, 0, 0,128,
+ 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,128, 0, 4,
+ 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 9, 0, 0, 0, 65,100,
+100, 65,108,112,104, 97, 0, 4, 18, 0, 0, 0, 67,111,110,118,101,114,116, 67,
+111,108,111,114, 83,112, 97, 99,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 8, 0,
+ 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0,
+ 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0,
+ 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0,
+ 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 12, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 17, 0, 0, 0,
+ 10, 0, 0, 0,104, 97,115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 6, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 18, 0, 0, 0,
+ 0, 7, 0, 15, 30, 0, 0, 0, 90, 64, 0, 0, 22, 64, 1,128,197, 1, 0, 0,
+198, 65,192, 3, 11,130, 64, 0, 28, 2, 0, 1,220,129, 0, 0, 64, 0,128, 3,
+197, 1, 0, 0,198,193,192, 3, 0, 2, 0, 0, 67, 2, 0, 5,192, 2,128, 0,
+220,129,128, 2,154, 0, 0, 0, 22, 64, 0,128, 11, 2,193, 3, 28, 66, 0, 1,
+ 5, 2, 0, 0, 6, 66, 65, 4, 64, 2, 0, 0,128, 2,128, 3,192, 2,128, 1,
+ 0, 3, 0, 2, 64, 3,128, 2,128, 3, 0, 3, 28,130,128, 3, 64, 2,128, 3,
+ 30, 2,128, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0,
+ 4, 18, 0, 0, 0, 67,111,108,111,114, 77,111,100,101, 84,111, 66,105,116,109,
+ 97,112, 0, 4, 11, 0, 0, 0, 67,111,108,111,114, 83,112, 97, 99,101, 0, 4,
+ 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 9, 0, 0, 0, 65,100,100, 65,108,112,104, 97, 0, 4, 16, 0, 0, 0,
+ 67,111,110,118,101,114,116, 84,111, 66,105,116,109, 97,112, 0, 0, 0, 0, 0,
+ 30, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,
+ 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0,
+ 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0,
+ 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0,
+ 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0,
+ 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0,
+ 18, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,
+101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 12, 0, 0, 0, 99,111,108,111,114, 95,
+115,112, 97, 99,101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0,104, 97,
+115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0,
+ 99,112,120, 50,114,101, 97,108, 0, 0, 0, 0, 0, 29, 0, 0, 0, 6, 0, 0,
+ 0,103, 97,109,109, 97, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0, 97,
+ 98,115,115,111,108,117,116,101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0,
+ 0, 99, 97,115,116, 95,109,111,100,101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 14, 0, 0, 0, 29, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0,
+ 0, 7, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 18, 0, 0,
+ 0, 13, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_convert.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_convert_be32.loh b/im/src/lua5/loh/im_convert_be32.loh
new file mode 100755
index 0000000..eebe1de
--- /dev/null
+++ b/im/src/lua5/loh/im_convert_be32.loh
@@ -0,0 +1,87 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_convert_be32.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_convert_be32.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 0, 4, 4, 4, 8, 0, 0, 0, 0, 21, 64,108,117, 97,
+ 53, 47,105,109, 95, 99,111,110,118,101,114,116, 46,108,117, 97, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0,
+100,128,128, 64, 9, 0, 0, 0, 5, 0, 0, 64,100,129, 0, 64, 9, 0, 0, 0,
+ 5, 0, 0,128,100,129,128, 64, 9, 0,128, 0, 30, 0, 0, 0, 4, 4, 0, 0,
+ 0, 3,105,109, 0, 4, 0, 0, 0, 19, 67,111,110,118,101,114,116, 68, 97,116,
+ 97, 84,121,112,101, 78,101,119, 0, 4, 0, 0, 0, 21, 67,111,110,118,101,114,
+116, 67,111,108,111,114, 83,112, 97, 99,101, 78,101,119, 0, 4, 0, 0, 0, 19,
+ 67,111,110,118,101,114,116, 84,111, 66,105,116,109, 97,112, 78,101,119, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 6, 0, 14, 0,
+ 0, 0, 18, 0, 0, 1,133, 3, 64, 65,134, 0, 0, 1,192, 5, 0, 2, 3, 0,
+128, 2,192, 3, 0,129,156, 0, 0, 1,197, 3,192,129,198, 0, 0, 2, 0, 3,
+ 0, 2, 64, 1, 0, 2,128, 1,128, 2,192, 2, 0, 3, 0, 2,128, 3, 64, 3,
+128,129,220, 3, 0, 2, 0, 1,128, 1,222, 0,128, 0, 30, 0, 0, 0, 3, 4,
+ 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 16, 67,111,110,118,101,114,
+116, 68, 97,116, 97, 84,121,112,101, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0,
+ 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
+ 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0,
+ 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0,
+ 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 10,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10,
+100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 9, 99,112,120, 50,114,101, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 6,103, 97,109,109, 97, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0,
+ 10, 97, 98,115,115,111,108,117,116,101, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 10, 99, 97,115,116, 95,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0, 6, 0,
+ 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 11, 0,
+ 3, 0, 8, 0, 0, 0, 18, 0, 0, 0,197, 1,192, 64,198, 0, 0, 1, 0, 3,
+ 0, 1, 67, 0,128, 1,192, 2,128,128,220, 0, 0, 0,154,128, 0, 64, 22, 1,
+192,129, 11, 1, 0, 65, 28, 0, 0, 1, 5, 2, 64,193, 6, 0, 0, 1, 64, 1,
+128, 1,128, 1,128,129, 28, 1,128, 1, 64, 1,128, 1, 30, 0,128, 0, 30, 0,
+ 0, 0, 4, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 9, 65,100,
+100, 65,108,112,104, 97, 0, 4, 0, 0, 0, 18, 67,111,110,118,101,114,116, 67,
+111,108,111,114, 83,112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0,
+ 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0,
+ 0, 8, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0,
+ 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0,
+ 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 10,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 12,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 17,
+ 0, 0, 0, 10,104, 97,115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0, 6,
+ 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 18,
+ 0, 7, 0, 15, 0, 0, 0, 30, 0, 0, 64, 90,128, 1, 64, 22, 0, 0, 1,197,
+ 3,192, 65,198, 0, 64,130, 11, 1, 0, 2, 28, 0, 0,129,220, 3,128, 0, 64,
+ 0, 0, 1,197, 3,192,193,198, 0, 0, 2, 0, 5, 0, 2, 67, 0,128, 2,192,
+ 2,128,129,220, 0, 0, 0,154,128, 0, 64, 22, 3,193, 2, 11, 1, 0, 66, 28,
+ 0, 0, 2, 5, 4, 65, 66, 6, 0, 0, 2, 64, 3,128, 2,128, 1,128, 2,192,
+ 2, 0, 3, 0, 2,128, 3, 64, 3, 0, 3,128, 3,128,130, 28, 3,128, 2, 64,
+ 1,128, 2, 30, 0,128, 0, 30, 0, 0, 0, 6, 4, 0, 0, 0, 3,105,109, 0,
+ 4, 0, 0, 0, 18, 67,111,108,111,114, 77,111,100,101, 84,111, 66,105,116,109,
+ 97,112, 0, 4, 0, 0, 0, 11, 67,111,108,111,114, 83,112, 97, 99,101, 0, 4,
+ 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 0, 0, 0, 9, 65,100,100, 65,108,112,104, 97, 0, 4, 0, 0, 0, 16,
+ 67,111,110,118,101,114,116, 84,111, 66,105,116,109, 97,112, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 18, 0, 0, 0, 8, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,
+101, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 12, 99,111,108,111,114, 95,
+115,112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10,104, 97,
+115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 9,
+ 99,112,120, 50,114,101, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0,
+ 6,103, 97,109,109, 97, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 97,
+ 98,115,115,111,108,117,116,101, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0,
+ 10, 99, 97,115,116, 95,109,111,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0,
+ 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0, 14, 0, 0, 0,
+ 29, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0,
+ 2, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0,
+ 18, 0, 0, 0, 13, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_convert_be32.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_convert_be64.loh b/im/src/lua5/loh/im_convert_be64.loh
new file mode 100644
index 0000000..52c5ec4
--- /dev/null
+++ b/im/src/lua5/loh/im_convert_be64.loh
@@ -0,0 +1,95 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_convert_be64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_convert_be64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95, 99,111,110,118,101,114,116, 46,108,117, 97,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 5, 0, 0,
+ 0,100, 0, 0, 0, 9, 64,128,128, 5, 0, 0, 0,100, 64, 0, 0, 9, 64, 0,
+129, 5, 0, 0, 0,100,128, 0, 0, 9, 64,128,129, 30, 0,128, 0, 4, 0, 0,
+ 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 19, 0, 0, 0, 0, 0,
+ 0, 0, 67,111,110,118,101,114,116, 68, 97,116, 97, 84,121,112,101, 78,101,119,
+ 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,101,114,116, 67,111,108,
+111,114, 83,112, 97, 99,101, 78,101,119, 0, 4, 19, 0, 0, 0, 0, 0, 0, 0,
+ 67,111,110,118,101,114,116, 84,111, 66,105,116,109, 97,112, 78,101,119, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0,
+ 6, 0, 14, 18, 0, 0, 0,133, 1, 0, 0,134, 65, 64, 3,192, 1, 0, 0, 3,
+ 2, 0, 5,192, 2,128, 0,156,129, 0, 3,197, 1, 0, 0,198,129,192, 3, 0,
+ 2, 0, 0, 64, 2, 0, 3,128, 2, 0, 1,192, 2,128, 1, 0, 3, 0, 2, 64,
+ 3,128, 2,220,129,128, 3, 0, 2, 0, 3,222, 1,128, 1, 30, 0,128, 0, 3,
+ 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0,
+ 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,101,114,116, 68, 97,116,
+ 97, 84,121,112,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 3, 0, 0, 0, 3, 0,
+ 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0,
+ 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 99,112,120, 50,114,101, 97,108, 0, 0,
+ 0, 0, 0, 17, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,103, 97,109,109, 97,
+ 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 97, 98,115,
+115,111,108,117,116,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 99, 97,115,116, 95,109,111,100,101, 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 6,
+ 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 11, 0, 0, 0, 0, 3, 0, 8, 18, 0, 0, 0,197, 0, 0, 0,198,
+ 64,192, 1, 0, 1, 0, 0, 67, 1, 0, 3,192, 1,128, 0,220,128,128, 2,154,
+ 0, 0, 0, 22, 64, 0,128, 11,129,192, 1, 28, 65, 0, 1, 5, 1, 0, 0, 6,
+193, 64, 2, 64, 1, 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30,
+ 1,128, 1, 30, 0,128, 0, 4, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,
+105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 65,100,
+100, 65,108,112,104, 97, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,
+101,114,116, 67,111,108,111,114, 83,112, 97, 99,101, 0, 0, 0, 0, 0, 18, 0,
+ 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0,
+ 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0,
+ 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0,
+ 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 17, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+104, 97,115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 6, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0,
+ 18, 0, 0, 0, 0, 7, 0, 15, 30, 0, 0, 0, 90, 64, 0, 0, 22, 64, 1,128,
+197, 1, 0, 0,198, 65,192, 3, 11,130, 64, 0, 28, 2, 0, 1,220,129, 0, 0,
+ 64, 0,128, 3,197, 1, 0, 0,198,193,192, 3, 0, 2, 0, 0, 67, 2, 0, 5,
+192, 2,128, 0,220,129,128, 2,154, 0, 0, 0, 22, 64, 0,128, 11, 2,193, 3,
+ 28, 66, 0, 1, 5, 2, 0, 0, 6, 66, 65, 4, 64, 2, 0, 0,128, 2,128, 3,
+192, 2,128, 1, 0, 3, 0, 2, 64, 3,128, 2,128, 3, 0, 3, 28,130,128, 3,
+ 64, 2,128, 3, 30, 2,128, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0,
+ 0, 0, 0, 0, 0,105,109, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 67,111,108,
+111,114, 77,111,100,101, 84,111, 66,105,116,109, 97,112, 0, 4, 11, 0, 0, 0,
+ 0, 0, 0, 0, 67,111,108,111,114, 83,112, 97, 99,101, 0, 4, 17, 0, 0, 0,
+ 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 65,100,100, 65,108,112,104, 97, 0, 4,
+ 16, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,101,114,116, 84,111, 66,105,116,
+109, 97,112, 0, 0, 0, 0, 0, 30, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,
+ 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,
+ 14, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0,
+ 15, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0,
+ 16, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0,
+ 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0,
+ 17, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 29, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,
+101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,104, 97,
+115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 99,112,120, 50,114,101, 97,108, 0, 0, 0, 0, 0, 29, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0,103, 97,109,109, 97, 0, 0, 0, 0, 0, 29,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 97, 98,115,115,111,108,117,116,101,
+ 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 99, 97,115,
+116, 95,109,111,100,101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 14, 0, 0, 0, 29, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0,
+ 0, 7, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 18, 0, 0,
+ 0, 13, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_convert_be64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_convert_le64.loh b/im/src/lua5/loh/im_convert_le64.loh
new file mode 100755
index 0000000..e2d2a06
--- /dev/null
+++ b/im/src/lua5/loh/im_convert_le64.loh
@@ -0,0 +1,95 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_convert_le64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_convert_le64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95, 99,111,110,118,101,114,116, 46,108,117, 97,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 5, 0, 0,
+ 0,100, 0, 0, 0, 9, 64,128,128, 5, 0, 0, 0,100, 64, 0, 0, 9, 64, 0,
+129, 5, 0, 0, 0,100,128, 0, 0, 9, 64,128,129, 30, 0,128, 0, 4, 0, 0,
+ 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 19, 0, 0, 0, 0, 0,
+ 0, 0, 67,111,110,118,101,114,116, 68, 97,116, 97, 84,121,112,101, 78,101,119,
+ 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,101,114,116, 67,111,108,
+111,114, 83,112, 97, 99,101, 78,101,119, 0, 4, 19, 0, 0, 0, 0, 0, 0, 0,
+ 67,111,110,118,101,114,116, 84,111, 66,105,116,109, 97,112, 78,101,119, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0,
+ 6, 0, 14, 18, 0, 0, 0,133, 1, 0, 0,134, 65, 64, 3,192, 1, 0, 0, 3,
+ 2, 0, 5,192, 2,128, 0,156,129, 0, 3,197, 1, 0, 0,198,129,192, 3, 0,
+ 2, 0, 0, 64, 2, 0, 3,128, 2, 0, 1,192, 2,128, 1, 0, 3, 0, 2, 64,
+ 3,128, 2,220,129,128, 3, 0, 2, 0, 3,222, 1,128, 1, 30, 0,128, 0, 3,
+ 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0,
+ 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,101,114,116, 68, 97,116,
+ 97, 84,121,112,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 3, 0, 0, 0, 3, 0,
+ 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0,
+ 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 99,112,120, 50,114,101, 97,108, 0, 0,
+ 0, 0, 0, 17, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,103, 97,109,109, 97,
+ 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 97, 98,115,
+115,111,108,117,116,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 99, 97,115,116, 95,109,111,100,101, 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 6,
+ 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 11, 0, 0, 0, 0, 3, 0, 8, 18, 0, 0, 0,197, 0, 0, 0,198,
+ 64,192, 1, 0, 1, 0, 0, 67, 1, 0, 3,192, 1,128, 0,220,128,128, 2,154,
+ 0, 0, 0, 22, 64, 0,128, 11,129,192, 1, 28, 65, 0, 1, 5, 1, 0, 0, 6,
+193, 64, 2, 64, 1, 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30,
+ 1,128, 1, 30, 0,128, 0, 4, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,
+105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 65,100,
+100, 65,108,112,104, 97, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,
+101,114,116, 67,111,108,111,114, 83,112, 97, 99,101, 0, 0, 0, 0, 0, 18, 0,
+ 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0,
+ 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0,
+ 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0,
+ 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 17, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+104, 97,115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 6, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0,
+ 18, 0, 0, 0, 0, 7, 0, 15, 30, 0, 0, 0, 90, 64, 0, 0, 22, 64, 1,128,
+197, 1, 0, 0,198, 65,192, 3, 11,130, 64, 0, 28, 2, 0, 1,220,129, 0, 0,
+ 64, 0,128, 3,197, 1, 0, 0,198,193,192, 3, 0, 2, 0, 0, 67, 2, 0, 5,
+192, 2,128, 0,220,129,128, 2,154, 0, 0, 0, 22, 64, 0,128, 11, 2,193, 3,
+ 28, 66, 0, 1, 5, 2, 0, 0, 6, 66, 65, 4, 64, 2, 0, 0,128, 2,128, 3,
+192, 2,128, 1, 0, 3, 0, 2, 64, 3,128, 2,128, 3, 0, 3, 28,130,128, 3,
+ 64, 2,128, 3, 30, 2,128, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0,
+ 0, 0, 0, 0, 0,105,109, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 67,111,108,
+111,114, 77,111,100,101, 84,111, 66,105,116,109, 97,112, 0, 4, 11, 0, 0, 0,
+ 0, 0, 0, 0, 67,111,108,111,114, 83,112, 97, 99,101, 0, 4, 17, 0, 0, 0,
+ 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 65,100,100, 65,108,112,104, 97, 0, 4,
+ 16, 0, 0, 0, 0, 0, 0, 0, 67,111,110,118,101,114,116, 84,111, 66,105,116,
+109, 97,112, 0, 0, 0, 0, 0, 30, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,
+ 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0,
+ 14, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0,
+ 15, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0,
+ 16, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0,
+ 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0,
+ 17, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 29, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,
+101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,104, 97,
+115, 95, 97,108,112,104, 97, 0, 0, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 99,112,120, 50,114,101, 97,108, 0, 0, 0, 0, 0, 29, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0,103, 97,109,109, 97, 0, 0, 0, 0, 0, 29,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 97, 98,115,115,111,108,117,116,101,
+ 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 99, 97,115,
+116, 95,109,111,100,101, 0, 0, 0, 0, 0, 29, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 14, 0, 0, 0, 29, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0,
+ 0, 7, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 18, 0, 0,
+ 0, 13, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_convert_le64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_fftw.loh b/im/src/lua5/loh/im_fftw.loh
new file mode 100755
index 0000000..9e7c78a
--- /dev/null
+++ b/im/src/lua5/loh/im_fftw.loh
@@ -0,0 +1,110 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_fftw51/im_fftw.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_fftw51/im_fftw.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 4, 4, 8, 0, 18, 0, 0, 0, 64,108,117, 97,
+ 53, 47,105,109, 95,102,102,116,119, 46,108,117, 97, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 8, 18, 0, 0, 0, 36, 0, 0, 0,100, 64, 0, 0,128, 0,
+128, 0,193, 0, 0, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64, 0, 0, 3, 1,
+ 0, 3,197,129, 0, 0,198,193,192, 3,156, 64, 0, 3,128, 0, 0, 0,193, 0,
+ 1, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64, 1, 0,156, 64, 0, 1, 30, 0,
+128, 0, 6, 0, 0, 0, 4, 24, 0, 0, 0, 80,114,111, 99,101,115,115, 67,114,
+111,115,115, 67,111,114,114,101,108, 97,116,105,111,110, 0, 4, 23, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 65,117,116,111, 67,111,114,114,101,108, 97,116,105,
+111,110, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 67, 70, 76, 79,
+ 65, 84, 0, 4, 11, 0, 0, 0, 80,114,111, 99,101,115,115, 70, 70, 84, 0, 4,
+ 12, 0, 0, 0, 80,114,111, 99,101,115,115, 73, 70, 70, 84, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 25, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0,
+ 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,
+133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0,
+ 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,
+137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0,
+ 4, 7, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 78,101,119,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 5, 1, 7,
+ 8, 23, 0, 0, 0,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0,
+ 0, 68, 1,128, 0,132, 1, 0, 1,196, 1,128, 1,156,128, 0, 3,196, 0, 0,
+ 2, 0, 1, 0, 0, 64, 1, 0, 1,133,129, 0, 0,192, 1,128, 0,156, 1, 0,
+ 1,220,128, 0, 0,218, 0, 0, 0, 22,192, 0,128, 0, 1,128, 1, 64, 1, 0,
+ 1, 30, 1,128, 1, 22, 0, 0,128,158, 0, 0, 1, 30, 0,128, 0, 3, 0, 0,
+ 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,
+114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,117,110,112, 97,
+ 99,107, 0, 0, 0, 0, 0, 23, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 20,
+ 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 24,
+ 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0,
+ 0, 22, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8,
+ 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0,114,101,116, 0, 15, 0, 0, 0, 22,
+ 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0,
+ 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0,
+ 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 6,
+ 0, 0, 0, 9, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 16, 0,
+ 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 50, 0, 0, 0,
+ 0, 5, 0, 11, 22, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,
+192, 1,128, 2, 5,130, 0, 0, 6,194, 64, 4, 65, 2, 1, 0,128, 2, 0, 0,
+ 28, 2,128, 1,156, 65, 0, 0,133, 1, 0, 0,192, 1, 0, 0, 1, 66, 1, 0,
+213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1,
+ 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0, 6, 0, 0, 0,
+ 4, 3, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 97,115,115,101,114,116, 0,
+ 4, 7, 0, 0, 0,115,116,114,105,110,103, 0, 4, 7, 0, 0, 0,102,111,114,
+109, 97,116, 0, 4, 24, 0, 0, 0,117,110,100,101,102,105,110,101,100, 32,102,
+117,110, 99,116,105,111,110, 32, 96, 37,115, 39, 0, 4, 4, 0, 0, 0, 78,101,
+119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 5, 2,
+ 7, 10, 24, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1,
+ 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1,
+ 0, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 5,130, 0, 0, 64, 2,
+ 0, 1, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22,192, 0,128, 64, 1,
+ 0, 2,128, 1,128, 1, 94, 1,128, 1, 22, 0, 0,128,222, 0, 0, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,
+109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0,
+ 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 44, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0,
+ 45, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0, 11, 0, 0, 0,
+115,114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 23, 0, 0, 0, 11,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 23, 0, 0, 0, 10, 0,
+ 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 23, 0, 0, 0,
+ 4, 0, 0, 0,114,101,116, 0, 16, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0,
+ 6, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0, 0,104,101,105,103,104,116,
+ 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0,
+ 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0,102,117,110, 99, 0,
+ 22, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0,
+ 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 49, 0, 0, 0, 49, 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0,
+102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 6, 0, 0,
+ 0,119,105,100,116,104, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0,104,
+101,105,103,104,116, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0, 0, 0, 99,111,
+108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 10, 0,
+ 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 21, 0, 0, 0,
+ 5, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0,
+ 0, 18, 0, 0, 0, 25, 0, 0, 0, 50, 0, 0, 0, 54, 0, 0, 0, 54, 0, 0,
+ 0, 54, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0,
+ 0, 55, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0,
+ 0, 57, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 2, 0, 0,
+ 0, 17, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101, 79,110,101, 68,101,115,
+116, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 84,119,111, 83,111,117,
+114, 99,101,115, 79,110,101, 68,101,115,116, 0, 2, 0, 0, 0, 17, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_fftw51/im_fftw.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_fftw_be32.loh b/im/src/lua5/loh/im_fftw_be32.loh
new file mode 100755
index 0000000..754d56a
--- /dev/null
+++ b/im/src/lua5/loh/im_fftw_be32.loh
@@ -0,0 +1,110 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_fftw51/im_fftw_be32.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_fftw51/im_fftw_be32.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 0, 4, 4, 4, 8, 0, 0, 0, 0, 18, 64,108,117, 97,
+ 53, 47,105,109, 95,102,102,116,119, 46,108,117, 97, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 8, 0, 0, 0, 18, 0, 0, 0, 36, 0, 0, 64,100, 0,128,
+ 0,128, 0, 0, 0,193, 1, 0, 64,156, 0, 0, 0,128, 0, 0, 64,193, 3, 0,
+ 1, 3, 0, 0,129,197, 3,192,193,198, 3, 0, 64,156, 0, 0, 0,128, 0, 1,
+ 0,193, 1, 0, 64,156, 0, 0, 0,128, 0, 1, 64,193, 1, 0, 64,156, 0,128,
+ 0, 30, 0, 0, 0, 6, 4, 0, 0, 0, 24, 80,114,111, 99,101,115,115, 67,114,
+111,115,115, 67,111,114,114,101,108, 97,116,105,111,110, 0, 4, 0, 0, 0, 23,
+ 80,114,111, 99,101,115,115, 65,117,116,111, 67,111,114,114,101,108, 97,116,105,
+111,110, 0, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 7, 67, 70, 76, 79,
+ 65, 84, 0, 4, 0, 0, 0, 11, 80,114,111, 99,101,115,115, 70, 70, 84, 0, 4,
+ 0, 0, 0, 12, 80,114,111, 99,101,115,115, 73, 70, 70, 84, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 25, 0, 5, 0, 9, 0, 0, 0, 17,
+ 0, 0, 1, 69, 2,128, 1, 70, 0, 0, 65,133, 2,128, 1,192, 1, 0, 65,156,
+ 0, 0, 1,133, 0, 0, 1,192, 0, 0,130, 1, 3,130, 1,213, 0, 0, 2, 36,
+ 0,128, 0, 0, 1, 0, 0, 0, 1,128, 0, 0, 2, 0, 0, 0, 2,128, 0, 0,
+ 3,130, 1,137, 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0,
+ 4, 0, 0, 0, 7, 97,115,115,101,114,116, 0, 4, 0, 0, 0, 4, 78,101,119,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 24, 5, 1, 7,
+ 8, 0, 0, 0, 23, 0, 0, 0,133, 1, 64, 64,134, 0, 0, 0,192, 0, 0, 1,
+ 4, 0,128, 1, 68, 1, 0, 1,132, 1,128, 1,196, 3, 0,128,156, 2, 0, 0,
+196, 0, 0, 1, 0, 1, 0, 1, 64, 0, 0,129,133, 0,128, 1,192, 1, 0, 1,
+156, 0, 0,128,220, 0, 0, 0,218,128, 0,192, 22, 1,128, 1, 0, 1, 0, 1,
+ 64, 1,128, 1, 30,128, 0, 0, 22, 1, 0, 0,158, 0,128, 0, 30, 0, 0, 0,
+ 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,
+114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 7,117,110,112, 97,
+ 99,107, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 15, 0, 0, 0, 15, 0,
+ 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0,
+ 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0,
+ 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 19, 0,
+ 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 22, 0,
+ 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 4, 97,114,103, 0, 0, 0, 0,
+ 0, 0, 0, 0, 22, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0,
+ 0, 0, 8, 0, 0, 0, 22, 0, 0, 0, 4,114,101,116, 0, 0, 0, 0, 15, 0,
+ 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0,
+ 7,104,101,105,103,104,116, 0, 0, 0, 0, 12, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0,
+ 0, 5,102,117,110, 99, 0, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9, 0,
+ 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13, 0,
+ 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0,
+ 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25, 0,
+ 0, 0, 6, 0, 0, 0, 9,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 12, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5,102,117,110, 99, 0, 0, 0, 0, 2,
+ 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 50,
+ 0, 5, 0, 11, 0, 0, 0, 22, 0, 0, 1, 69, 2,128, 1, 70, 0, 0, 65,133,
+ 2,128, 1,192, 0, 0,130, 5, 4, 64,194, 6, 0, 1, 2, 65, 0, 0, 2,128,
+ 1,128, 2, 28, 0, 0, 65,156, 0, 0, 1,133, 0, 0, 1,192, 0, 1, 66, 1,
+ 3,130, 1,213, 0, 0, 2, 36, 0,128, 0, 0, 1, 0, 0, 0, 1,128, 0, 0,
+ 2, 0, 0, 0, 2,128, 0, 0, 3,130, 1,137, 0,128, 0, 30, 0, 0, 0, 6,
+ 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 7, 97,115,115,101,114,116, 0,
+ 4, 0, 0, 0, 7,115,116,114,105,110,103, 0, 4, 0, 0, 0, 7,102,111,114,
+109, 97,116, 0, 4, 0, 0, 0, 24,117,110,100,101,102,105,110,101,100, 32,102,
+117,110, 99,116,105,111,110, 32, 96, 37,115, 39, 0, 4, 0, 0, 0, 4, 78,101,
+119, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 49, 5, 2,
+ 7, 10, 0, 0, 0, 24, 0, 0, 0,197, 1,192, 64,198, 0, 0, 1, 0, 0, 0,
+ 1, 68, 0,128, 1,132, 1, 0, 1,196, 1,128, 2, 4, 3, 0,128,220, 2, 0,
+ 1, 4, 0, 0, 1, 64, 0,128, 1,128, 1,128, 1,192, 0, 0,130, 5, 1, 0,
+ 2, 64, 1, 0, 2, 28, 0, 0,129, 28, 0, 0, 1, 26,128, 0,192, 22, 2, 0,
+ 1, 64, 1,128, 1,128, 1,128, 1, 94,128, 0, 0, 22, 1, 0, 0,222, 0,128,
+ 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,
+109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0,
+ 7,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40,
+ 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40,
+ 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43,
+ 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43,
+ 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45,
+ 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0, 11,
+115,114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 11,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 23, 0, 0, 0, 4, 97,114,103, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0,
+ 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0, 8, 0, 0, 0, 23,
+ 0, 0, 0, 4,114,101,116, 0, 0, 0, 0, 16, 0, 0, 0, 23, 0, 0, 0, 5,
+ 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0, 7,104,101,105,103,104,116,
+ 0, 0, 0, 0, 12, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0,
+ 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 5,102,117,110, 99, 0,
+ 0, 0, 0, 22, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0, 35,
+ 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35,
+ 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38,
+ 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49,
+ 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0, 9,
+102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0,
+ 6,119,105,100,116,104, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7,104,
+101,105,103,104,116, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 99,111,
+108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0,
+ 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+ 0, 0, 0, 5,102,117,110, 99, 0, 0, 0, 0, 2, 0, 0, 0, 21, 0, 0, 0,
+ 0, 0, 0, 0, 18, 0, 0, 0, 25, 0, 0, 0, 50, 0, 0, 0, 54, 0, 0, 0,
+ 54, 0, 0, 0, 54, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0,
+ 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0,
+ 56, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0,
+ 2, 0, 0, 0, 17, 79,110,101, 83,111,117,114, 99,101, 79,110,101, 68,101,115,
+116, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 84,119,111, 83,111,117,
+114, 99,101,115, 79,110,101, 68,101,115,116, 0, 0, 0, 0, 2, 0, 0, 0, 17,
+ 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_fftw51/im_fftw_be32.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_fftw_be64.loh b/im/src/lua5/loh/im_fftw_be64.loh
new file mode 100644
index 0000000..3b1a6cb
--- /dev/null
+++ b/im/src/lua5/loh/im_fftw_be64.loh
@@ -0,0 +1,122 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_fftw51/im_fftw_be64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_fftw51/im_fftw_be64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 18, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,102,102,116,119, 46,108,117, 97, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 18, 0, 0, 0, 36, 0, 0, 0,100, 64,
+ 0, 0,128, 0,128, 0,193, 0, 0, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64,
+ 0, 0, 3, 1, 0, 3,197,129, 0, 0,198,193,192, 3,156, 64, 0, 3,128, 0,
+ 0, 0,193, 0, 1, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64, 1, 0,156, 64,
+ 0, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 24, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 67,114,111,115,115, 67,111,114,114,101,108, 97,116,105,
+111,110, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,
+117,116,111, 67,111,114,114,101,108, 97,116,105,111,110, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 67, 70, 76, 79,
+ 65, 84, 0, 4, 11, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 70,
+ 70, 84, 0, 4, 12, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,
+ 70, 70, 84, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 25, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,
+133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0,
+ 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1,
+ 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0,
+ 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0, 24, 0, 0, 0, 5, 1, 7, 8, 23, 0, 0, 0,133, 0, 0, 0,134, 64, 64,
+ 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0, 1,196, 1,128,
+ 1,156,128, 0, 3,196, 0, 0, 2, 0, 1, 0, 0, 64, 1, 0, 1,133,129, 0,
+ 0,192, 1,128, 0,156, 1, 0, 1,220,128, 0, 0,218, 0, 0, 0, 22,192, 0,
+128, 0, 1,128, 1, 64, 1, 0, 1, 30, 1,128, 1, 22, 0, 0,128,158, 0, 0,
+ 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97,
+ 99,107, 0, 0, 0, 0, 0, 23, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 20,
+ 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 24,
+ 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 97,114,103, 0, 0, 0, 0, 0, 22, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 22, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 15, 0, 0, 0, 22, 0, 0, 0, 5,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,
+110, 99, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10,
+ 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 9,
+ 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,
+111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0,
+ 50, 0, 0, 0, 0, 5, 0, 11, 22, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,
+133, 65, 0, 0,192, 1,128, 2, 5,130, 0, 0, 6,194, 64, 4, 65, 2, 1, 0,
+128, 2, 0, 0, 28, 2,128, 1,156, 65, 0, 0,133, 1, 0, 0,192, 1, 0, 0,
+ 1, 66, 1, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1,
+ 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0,
+ 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 7, 0, 0, 0, 0, 0, 0,
+ 0,115,116,114,105,110,103, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,102,111,114,
+109, 97,116, 0, 4, 24, 0, 0, 0, 0, 0, 0, 0,117,110,100,101,102,105,110,
+101,100, 32,102,117,110, 99,116,105,111,110, 32, 96, 37,115, 39, 0, 4, 4, 0,
+ 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 5, 2, 7, 10, 24, 0, 0, 0,197, 0,
+ 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1, 0, 0,132, 1,128, 0,196, 1,
+ 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1, 0, 2, 64, 1, 0, 0,128, 1,
+128, 0,192, 1,128, 1, 5,130, 0, 0, 64, 2, 0, 1, 28, 2, 0, 1, 28,129,
+ 0, 0, 26, 1, 0, 0, 22,192, 0,128, 64, 1, 0, 2,128, 1,128, 1, 94, 1,
+128, 1, 22, 0, 0,128,222, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3,
+ 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,
+109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 24, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0,
+ 45, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0,
+ 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 49, 0, 0,
+ 0, 0, 0, 23, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 50, 0, 0, 0, 0, 0, 23, 0, 0, 0, 4, 0, 0, 0, 0, 0,
+ 0, 0, 97,114,103, 0, 0, 0, 0, 0, 23, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 23, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 16, 0, 0, 0, 23, 0, 0, 0,
+ 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0, 0, 0,
+ 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,
+117,110, 99, 0, 22, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0,
+ 38, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0,
+ 0, 21, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0,
+ 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,
+116, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,
+108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0,
+ 21, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0,
+ 0, 21, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 25, 0, 0, 0, 50, 0, 0,
+ 0, 54, 0, 0, 0, 54, 0, 0, 0, 54, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0,
+ 0, 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0,
+ 0, 56, 0, 0, 0, 56, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0,
+ 0, 57, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 79,110,101,
+ 83,111,117,114, 99,101, 79,110,101, 68,101,115,116, 0, 1, 0, 0, 0, 17, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 84,119,111, 83,111,117,114, 99,101,115,
+ 79,110,101, 68,101,115,116, 0, 2, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
+
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_fftw51/im_fftw_be64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_fftw_le64.loh b/im/src/lua5/loh/im_fftw_le64.loh
new file mode 100755
index 0000000..c5b497a
--- /dev/null
+++ b/im/src/lua5/loh/im_fftw_le64.loh
@@ -0,0 +1,122 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_fftw51/im_fftw_le64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_fftw51/im_fftw_le64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 18, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,102,102,116,119, 46,108,117, 97, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 18, 0, 0, 0, 36, 0, 0, 0,100, 64,
+ 0, 0,128, 0,128, 0,193, 0, 0, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64,
+ 0, 0, 3, 1, 0, 3,197,129, 0, 0,198,193,192, 3,156, 64, 0, 3,128, 0,
+ 0, 0,193, 0, 1, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64, 1, 0,156, 64,
+ 0, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 24, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 67,114,111,115,115, 67,111,114,114,101,108, 97,116,105,
+111,110, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,
+117,116,111, 67,111,114,114,101,108, 97,116,105,111,110, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 67, 70, 76, 79,
+ 65, 84, 0, 4, 11, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 70,
+ 70, 84, 0, 4, 12, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,
+ 70, 70, 84, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 25, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,
+133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0,
+ 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1,
+ 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0,
+ 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0, 24, 0, 0, 0, 5, 1, 7, 8, 23, 0, 0, 0,133, 0, 0, 0,134, 64, 64,
+ 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0, 1,196, 1,128,
+ 1,156,128, 0, 3,196, 0, 0, 2, 0, 1, 0, 0, 64, 1, 0, 1,133,129, 0,
+ 0,192, 1,128, 0,156, 1, 0, 1,220,128, 0, 0,218, 0, 0, 0, 22,192, 0,
+128, 0, 1,128, 1, 64, 1, 0, 1, 30, 1,128, 1, 22, 0, 0,128,158, 0, 0,
+ 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97,
+ 99,107, 0, 0, 0, 0, 0, 23, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 20,
+ 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 24,
+ 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 97,114,103, 0, 0, 0, 0, 0, 22, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 22, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 15, 0, 0, 0, 22, 0, 0, 0, 5,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,
+110, 99, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10,
+ 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 9,
+ 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,
+111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0,
+ 50, 0, 0, 0, 0, 5, 0, 11, 22, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,
+133, 65, 0, 0,192, 1,128, 2, 5,130, 0, 0, 6,194, 64, 4, 65, 2, 1, 0,
+128, 2, 0, 0, 28, 2,128, 1,156, 65, 0, 0,133, 1, 0, 0,192, 1, 0, 0,
+ 1, 66, 1, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1,
+ 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0,
+ 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 7, 0, 0, 0, 0, 0, 0,
+ 0,115,116,114,105,110,103, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,102,111,114,
+109, 97,116, 0, 4, 24, 0, 0, 0, 0, 0, 0, 0,117,110,100,101,102,105,110,
+101,100, 32,102,117,110, 99,116,105,111,110, 32, 96, 37,115, 39, 0, 4, 4, 0,
+ 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 5, 2, 7, 10, 24, 0, 0, 0,197, 0,
+ 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1, 0, 0,132, 1,128, 0,196, 1,
+ 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1, 0, 2, 64, 1, 0, 0,128, 1,
+128, 0,192, 1,128, 1, 5,130, 0, 0, 64, 2, 0, 1, 28, 2, 0, 1, 28,129,
+ 0, 0, 26, 1, 0, 0, 22,192, 0,128, 64, 1, 0, 2,128, 1,128, 1, 94, 1,
+128, 1, 22, 0, 0,128,222, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3,
+ 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,
+109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 24, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0,
+ 45, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0,
+ 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 49, 0, 0,
+ 0, 0, 0, 23, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 50, 0, 0, 0, 0, 0, 23, 0, 0, 0, 4, 0, 0, 0, 0, 0,
+ 0, 0, 97,114,103, 0, 0, 0, 0, 0, 23, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 23, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 16, 0, 0, 0, 23, 0, 0, 0,
+ 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0, 0, 0,
+ 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,
+117,110, 99, 0, 22, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0,
+ 38, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0,
+ 0, 21, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0,
+ 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,
+116, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,
+108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0,
+ 21, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0,
+ 0, 21, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 25, 0, 0, 0, 50, 0, 0,
+ 0, 54, 0, 0, 0, 54, 0, 0, 0, 54, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0,
+ 0, 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0,
+ 0, 56, 0, 0, 0, 56, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0,
+ 0, 57, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 79,110,101,
+ 83,111,117,114, 99,101, 79,110,101, 68,101,115,116, 0, 1, 0, 0, 0, 17, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 84,119,111, 83,111,117,114, 99,101,115,
+ 79,110,101, 68,101,115,116, 0, 2, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0,
+
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_fftw51/im_fftw_le64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_fftw_le64w.loh b/im/src/lua5/loh/im_fftw_le64w.loh
new file mode 100755
index 0000000..51fec14
--- /dev/null
+++ b/im/src/lua5/loh/im_fftw_le64w.loh
@@ -0,0 +1,115 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_fftw51/im_fftw_le64w.lo")==0) lua_pcall(L, 0, 0, 0);
+*/
+/* ../obj/imlua_fftw51/im_fftw_le64w.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 18, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,102,102,116,119, 46,108,117, 97, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 18, 0, 0, 0, 36, 0, 0, 0,100, 64,
+ 0, 0,128, 0,128, 0,193, 0, 0, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64,
+ 0, 0, 3, 1, 0, 3,197,129, 0, 0,198,193,192, 3,156, 64, 0, 3,128, 0,
+ 0, 0,193, 0, 1, 0,156, 64, 0, 1,128, 0, 0, 0,193, 64, 1, 0,156, 64,
+ 0, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 24, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 67,114,111,115,115, 67,111,114,114,101,108, 97,116,105,
+111,110, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,
+117,116,111, 67,111,114,114,101,108, 97,116,105,111,110, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 67, 70, 76, 79,
+ 65, 84, 0, 4, 11, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 70,
+ 70, 84, 0, 4, 12, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,
+ 70, 70, 84, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 20, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,
+133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0,
+ 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1,
+ 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0,
+ 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0,
+ 0, 19, 0, 0, 0, 5, 1, 7, 8, 17, 0, 0, 0,133, 0, 0, 0,134, 64, 64,
+ 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0, 1,196, 1,128,
+ 1,156,128, 0, 3,196, 0, 0, 2, 0, 1, 0, 0, 64, 1, 0, 1,133,129, 0,
+ 0,192, 1,128, 0,156, 1, 0, 1,220, 64, 0, 0,158, 0, 0, 1, 30, 0,128,
+ 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0,
+ 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,
+101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 17, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 3, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,
+103,101, 0, 8, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,
+103,104,116, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,
+101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 8,
+ 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 12,
+ 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 19, 0, 0, 0, 19,
+ 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 19,
+ 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,
+117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116,
+ 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 41, 0, 0, 0, 0, 5, 0, 11,
+ 22, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,
+ 5,130, 0, 0, 6,194, 64, 4, 65, 2, 1, 0,128, 2, 0, 0, 28, 2,128, 1,
+156, 65, 0, 0,133, 1, 0, 0,192, 1, 0, 0, 1, 66, 1, 0,213, 1,130, 3,
+ 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2,
+ 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0,
+ 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,
+101,114,116, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,115,116,114,105,110,103, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0,102,111,114,109, 97,116, 0, 4, 24, 0, 0,
+ 0, 0, 0, 0, 0,117,110,100,101,102,105,110,101,100, 32,102,117,110, 99,116,
+105,111,110, 32, 96, 37,115, 39, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,
+119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 40, 0,
+ 0, 0, 5, 2, 7, 10, 18, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1,
+ 0, 0, 68, 1, 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128,
+ 0, 3, 4, 1, 0, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 5,130,
+ 0, 0, 64, 2, 0, 1, 28, 2, 0, 1, 28, 65, 0, 0,222, 0, 0, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17,
+ 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,
+115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0,
+ 0, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0,
+ 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 39, 0, 0, 0, 40, 0, 0, 0,
+ 4, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,
+101, 49, 0, 0, 0, 0, 0, 17, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 0, 17, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 17, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0,
+ 17, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,
+104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0,
+ 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0,102,117,110, 99, 0, 22, 0, 0, 0, 27, 0, 0, 0, 27, 0, 0, 0,
+ 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0,
+ 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 33, 0, 0, 0, 33, 0, 0, 0,
+ 33, 0, 0, 0, 33, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0,
+ 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101,
+ 0, 0, 0, 0, 0, 21, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,
+116,104, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,
+101,105,103,104,116, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0, 0, 0, 0, 0,
+ 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 21, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0,
+ 0, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,
+ 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 20, 0, 0,
+ 0, 41, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 46, 0, 0,
+ 0, 46, 0, 0, 0, 46, 0, 0, 0, 46, 0, 0, 0, 46, 0, 0, 0, 46, 0, 0,
+ 0, 47, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0,
+ 0, 48, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 79,110,101, 83,111,117,114, 99,101, 79,110,101, 68,101,115,116, 0, 1, 0,
+ 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 84,119,111, 83,111,117,
+114, 99,101,115, 79,110,101, 68,101,115,116, 0, 2, 0, 0, 0, 17, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_fftw51/im_fftw_le64w.lo")==0) lua_pcall(L, 0, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_image.loh b/im/src/lua5/loh/im_image.loh
new file mode 100644
index 0000000..c43eb8c
--- /dev/null
+++ b/im/src/lua5/loh/im_image.loh
@@ -0,0 +1,63 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_image.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_image.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 4, 4, 8, 0, 19, 0, 0, 0, 64,108,117, 97,
+ 53, 47,105,109, 95,105,109, 97,103,101, 46,108,117, 97, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 4, 0, 0, 0, 5, 0, 0, 0,100, 0, 0, 0, 9,
+ 64,128,128, 30, 0,128, 0, 2, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4,
+ 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 5, 0,
+ 10, 74, 0, 0, 0, 90, 64, 0, 0, 22,128, 0,128, 75, 1, 64, 0, 92,129, 0,
+ 1, 64, 0,128, 2,154, 64, 0, 0, 22,128, 0,128, 75, 65, 64, 0, 92,129, 0,
+ 1,128, 0,128, 2,218, 64, 0, 0, 22,128, 0,128, 75,129, 64, 0, 92,129, 0,
+ 1,192, 0,128, 2, 26, 65, 0, 0, 22,128, 0,128, 75,193, 64, 0, 92,129, 0,
+ 1, 0, 1,128, 2, 69, 1, 1, 0,128, 1,128, 0, 92,129, 0, 1, 23, 64,193,
+ 2, 22,192, 0,128, 64, 1,128, 0,128, 1, 0, 0, 92,129, 0, 1, 64, 0,128,
+ 2, 69, 1, 1, 0,128, 1, 0, 1, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,
+128, 64, 1, 0, 1,128, 1, 0, 0, 92,129, 0, 1,128, 0,128, 2, 69, 1, 1,
+ 0,128, 1,128, 1, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,128, 64, 1,128,
+ 1,128, 1, 0, 0, 92,129, 0, 1,192, 0,128, 2, 69, 1, 1, 0,128, 1, 0,
+ 2, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,128, 64, 1, 0, 2,128, 1, 0,
+ 0, 92,129, 0, 1, 0, 1,128, 2, 69,129, 1, 0, 70,193,193, 2,128, 1,128,
+ 0,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2, 92,129,128, 2,139, 1, 66,
+ 0, 0, 2,128, 2,156, 65,128, 1,139, 65, 66, 0,156,129, 0, 1,154, 1, 0,
+ 0, 22, 64, 0,128,139,129,194, 2,156, 65, 0, 1, 94, 1, 0, 1, 30, 0,128,
+ 0, 11, 0, 0, 0, 4, 6, 0, 0, 0, 87,105,100,116,104, 0, 4, 7, 0, 0,
+ 0, 72,101,105,103,104,116, 0, 4, 11, 0, 0, 0, 67,111,108,111,114, 83,112,
+ 97, 99,101, 0, 4, 9, 0, 0, 0, 68, 97,116, 97, 84,121,112,101, 0, 4, 5,
+ 0, 0, 0,116,121,112,101, 0, 4, 9, 0, 0, 0,102,117,110, 99,116,105,111,
+110, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 12, 0, 0, 0, 73,109, 97,103,101,
+ 67,114,101, 97,116,101, 0, 4, 15, 0, 0, 0, 67,111,112,121, 65,116,116,114,
+105, 98,117,116,101,115, 0, 4, 9, 0, 0, 0, 72, 97,115, 65,108,112,104, 97,
+ 0, 4, 9, 0, 0, 0, 65,100,100, 65,108,112,104, 97, 0, 0, 0, 0, 0, 74,
+ 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8,
+ 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10,
+ 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 16,
+ 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16,
+ 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20,
+ 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 21,
+ 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22,
+ 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 6,
+ 0, 0, 0, 6, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 73, 0, 0,
+ 0, 6, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 73, 0, 0, 0, 7,
+ 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 73, 0, 0, 0, 12, 0,
+ 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 73, 0,
+ 0, 0, 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0,
+ 73, 0, 0, 0, 10, 0, 0, 0,110,101,119, 95,105,109, 97,103,101, 0, 63, 0,
+ 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 24, 0,
+ 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_image.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_image_be32.loh b/im/src/lua5/loh/im_image_be32.loh
new file mode 100755
index 0000000..04bafc0
--- /dev/null
+++ b/im/src/lua5/loh/im_image_be32.loh
@@ -0,0 +1,63 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_image_be32.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_image_be32.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 0, 4, 4, 4, 8, 0, 0, 0, 0, 19, 64,108,117, 97,
+ 53, 47,105,109, 95,105,109, 97,103,101, 46,108,117, 97, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0,100,128,
+128, 64, 9, 0,128, 0, 30, 0, 0, 0, 2, 4, 0, 0, 0, 3,105,109, 0, 4,
+ 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 24, 0, 5, 0,
+ 10, 0, 0, 0, 74, 0, 0, 64, 90,128, 0,128, 22, 0, 64, 1, 75, 1, 0,129,
+ 92, 2,128, 0, 64, 0, 0, 64,154,128, 0,128, 22, 0, 64, 65, 75, 1, 0,129,
+ 92, 2,128, 0,128, 0, 0, 64,218,128, 0,128, 22, 0, 64,129, 75, 1, 0,129,
+ 92, 2,128, 0,192, 0, 0, 65, 26,128, 0,128, 22, 0, 64,193, 75, 1, 0,129,
+ 92, 2,128, 1, 0, 0, 1, 1, 69, 0,128, 1,128, 1, 0,129, 92, 2,193, 64,
+ 23,128, 0,192, 22, 0,128, 1, 64, 0, 0, 1,128, 1, 0,129, 92, 2,128, 0,
+ 64, 0, 1, 1, 69, 1, 0, 1,128, 1, 0,129, 92, 2,193, 64, 23,128, 0,192,
+ 22, 1, 0, 1, 64, 0, 0, 1,128, 1, 0,129, 92, 2,128, 0,128, 0, 1, 1,
+ 69, 1,128, 1,128, 1, 0,129, 92, 2,193, 64, 23,128, 0,192, 22, 1,128, 1,
+ 64, 0, 0, 1,128, 1, 0,129, 92, 2,128, 0,192, 0, 1, 1, 69, 2, 0, 1,
+128, 1, 0,129, 92, 2,193, 64, 23,128, 0,192, 22, 2, 0, 1, 64, 0, 0, 1,
+128, 1, 0,129, 92, 2,128, 1, 0, 0, 1,129, 69, 2,193,193, 70, 0,128, 1,
+128, 1, 0, 1,192, 1,128, 2, 0, 2, 0, 2, 64, 2,128,129, 92, 0, 66, 1,
+139, 2,128, 2, 0, 1,128, 65,156, 0, 66, 65,139, 1, 0,129,156, 0, 0, 1,
+154,128, 0, 64, 22, 2,194,129,139, 1, 0, 65,156, 1, 0, 1, 94, 0,128, 0,
+ 30, 0, 0, 0, 11, 4, 0, 0, 0, 6, 87,105,100,116,104, 0, 4, 0, 0, 0,
+ 7, 72,101,105,103,104,116, 0, 4, 0, 0, 0, 11, 67,111,108,111,114, 83,112,
+ 97, 99,101, 0, 4, 0, 0, 0, 9, 68, 97,116, 97, 84,121,112,101, 0, 4, 0,
+ 0, 0, 5,116,121,112,101, 0, 4, 0, 0, 0, 9,102,117,110, 99,116,105,111,
+110, 0, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 12, 73,109, 97,103,101,
+ 67,114,101, 97,116,101, 0, 4, 0, 0, 0, 15, 67,111,112,121, 65,116,116,114,
+105, 98,117,116,101,115, 0, 4, 0, 0, 0, 9, 72, 97,115, 65,108,112,104, 97,
+ 0, 4, 0, 0, 0, 9, 65,100,100, 65,108,112,104, 97, 0, 0, 0, 0, 0, 0,
+ 0, 0, 74, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0,
+ 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0,
+ 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0,
+ 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0,
+ 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0,
+ 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0,
+ 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0,
+ 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 16, 0,
+ 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0,
+ 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 17, 0,
+ 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0,
+ 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0,
+ 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 21, 0,
+ 0, 0, 21, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22, 0,
+ 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0,
+ 0, 0, 6, 0, 0, 0, 6,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0,
+ 73, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0,
+ 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0,
+ 0, 12, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0,
+ 0, 73, 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0,
+ 0, 0, 0, 73, 0, 0, 0, 10,110,101,119, 95,105,109, 97,103,101, 0, 0, 0,
+ 0, 63, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0,
+ 0, 24, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_image_be32.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_image_be64.loh b/im/src/lua5/loh/im_image_be64.loh
new file mode 100644
index 0000000..6aed993
--- /dev/null
+++ b/im/src/lua5/loh/im_image_be64.loh
@@ -0,0 +1,68 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_image_be64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_image_be64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 19, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,105,109, 97,103,101, 46,108,117, 97, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 0, 0, 0, 5, 0, 0, 0,100,
+ 0, 0, 0, 9, 64,128,128, 30, 0,128, 0, 2, 0, 0, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 5, 0, 10, 74, 0, 0,
+ 0, 90, 64, 0, 0, 22,128, 0,128, 75, 1, 64, 0, 92,129, 0, 1, 64, 0,128,
+ 2,154, 64, 0, 0, 22,128, 0,128, 75, 65, 64, 0, 92,129, 0, 1,128, 0,128,
+ 2,218, 64, 0, 0, 22,128, 0,128, 75,129, 64, 0, 92,129, 0, 1,192, 0,128,
+ 2, 26, 65, 0, 0, 22,128, 0,128, 75,193, 64, 0, 92,129, 0, 1, 0, 1,128,
+ 2, 69, 1, 1, 0,128, 1,128, 0, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,
+128, 64, 1,128, 0,128, 1, 0, 0, 92,129, 0, 1, 64, 0,128, 2, 69, 1, 1,
+ 0,128, 1, 0, 1, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,128, 64, 1, 0,
+ 1,128, 1, 0, 0, 92,129, 0, 1,128, 0,128, 2, 69, 1, 1, 0,128, 1,128,
+ 1, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,128, 64, 1,128, 1,128, 1, 0,
+ 0, 92,129, 0, 1,192, 0,128, 2, 69, 1, 1, 0,128, 1, 0, 2, 92,129, 0,
+ 1, 23, 64,193, 2, 22,192, 0,128, 64, 1, 0, 2,128, 1, 0, 0, 92,129, 0,
+ 1, 0, 1,128, 2, 69,129, 1, 0, 70,193,193, 2,128, 1,128, 0,192, 1, 0,
+ 1, 0, 2,128, 1, 64, 2, 0, 2, 92,129,128, 2,139, 1, 66, 0, 0, 2,128,
+ 2,156, 65,128, 1,139, 65, 66, 0,156,129, 0, 1,154, 1, 0, 0, 22, 64, 0,
+128,139,129,194, 2,156, 65, 0, 1, 94, 1, 0, 1, 30, 0,128, 0, 11, 0, 0,
+ 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 4, 11, 0, 0, 0, 0, 0, 0,
+ 0, 67,111,108,111,114, 83,112, 97, 99,101, 0, 4, 9, 0, 0, 0, 0, 0, 0,
+ 0, 68, 97,116, 97, 84,121,112,101, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,116,
+121,112,101, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,116,105,111,
+110, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 12, 0, 0, 0, 0,
+ 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 0, 4, 15, 0, 0, 0,
+ 0, 0, 0, 0, 67,111,112,121, 65,116,116,114,105, 98,117,116,101,115, 0, 4,
+ 9, 0, 0, 0, 0, 0, 0, 0, 72, 97,115, 65,108,112,104, 97, 0, 4, 9, 0,
+ 0, 0, 0, 0, 0, 0, 65,100,100, 65,108,112,104, 97, 0, 0, 0, 0, 0, 74,
+ 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8,
+ 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10,
+ 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 16,
+ 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16,
+ 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20,
+ 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 21,
+ 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22,
+ 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 6,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0,
+ 0, 73, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0,
+ 0, 0, 0, 73, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,
+116, 0, 0, 0, 0, 0, 73, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,
+108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 73, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0,
+ 73, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,110,101,119, 95,105,109, 97,103,
+101, 0, 63, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 0,
+ 0, 0, 24, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_image_be64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_image_le64.loh b/im/src/lua5/loh/im_image_le64.loh
new file mode 100755
index 0000000..6a4d127
--- /dev/null
+++ b/im/src/lua5/loh/im_image_le64.loh
@@ -0,0 +1,68 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua51/im_image_le64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua51/im_image_le64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 19, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,105,109, 97,103,101, 46,108,117, 97, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 0, 0, 0, 5, 0, 0, 0,100,
+ 0, 0, 0, 9, 64,128,128, 30, 0,128, 0, 2, 0, 0, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 5, 0, 10, 74, 0, 0,
+ 0, 90, 64, 0, 0, 22,128, 0,128, 75, 1, 64, 0, 92,129, 0, 1, 64, 0,128,
+ 2,154, 64, 0, 0, 22,128, 0,128, 75, 65, 64, 0, 92,129, 0, 1,128, 0,128,
+ 2,218, 64, 0, 0, 22,128, 0,128, 75,129, 64, 0, 92,129, 0, 1,192, 0,128,
+ 2, 26, 65, 0, 0, 22,128, 0,128, 75,193, 64, 0, 92,129, 0, 1, 0, 1,128,
+ 2, 69, 1, 1, 0,128, 1,128, 0, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,
+128, 64, 1,128, 0,128, 1, 0, 0, 92,129, 0, 1, 64, 0,128, 2, 69, 1, 1,
+ 0,128, 1, 0, 1, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,128, 64, 1, 0,
+ 1,128, 1, 0, 0, 92,129, 0, 1,128, 0,128, 2, 69, 1, 1, 0,128, 1,128,
+ 1, 92,129, 0, 1, 23, 64,193, 2, 22,192, 0,128, 64, 1,128, 1,128, 1, 0,
+ 0, 92,129, 0, 1,192, 0,128, 2, 69, 1, 1, 0,128, 1, 0, 2, 92,129, 0,
+ 1, 23, 64,193, 2, 22,192, 0,128, 64, 1, 0, 2,128, 1, 0, 0, 92,129, 0,
+ 1, 0, 1,128, 2, 69,129, 1, 0, 70,193,193, 2,128, 1,128, 0,192, 1, 0,
+ 1, 0, 2,128, 1, 64, 2, 0, 2, 92,129,128, 2,139, 1, 66, 0, 0, 2,128,
+ 2,156, 65,128, 1,139, 65, 66, 0,156,129, 0, 1,154, 1, 0, 0, 22, 64, 0,
+128,139,129,194, 2,156, 65, 0, 1, 94, 1, 0, 1, 30, 0,128, 0, 11, 0, 0,
+ 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 4, 11, 0, 0, 0, 0, 0, 0,
+ 0, 67,111,108,111,114, 83,112, 97, 99,101, 0, 4, 9, 0, 0, 0, 0, 0, 0,
+ 0, 68, 97,116, 97, 84,121,112,101, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,116,
+121,112,101, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,116,105,111,
+110, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 12, 0, 0, 0, 0,
+ 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 0, 4, 15, 0, 0, 0,
+ 0, 0, 0, 0, 67,111,112,121, 65,116,116,114,105, 98,117,116,101,115, 0, 4,
+ 9, 0, 0, 0, 0, 0, 0, 0, 72, 97,115, 65,108,112,104, 97, 0, 4, 9, 0,
+ 0, 0, 0, 0, 0, 0, 65,100,100, 65,108,112,104, 97, 0, 0, 0, 0, 0, 74,
+ 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8,
+ 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10,
+ 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 11,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14,
+ 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 16,
+ 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16,
+ 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 17,
+ 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20,
+ 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 21,
+ 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 22,
+ 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 6,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0,
+ 0, 73, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0,
+ 0, 0, 0, 73, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,
+116, 0, 0, 0, 0, 0, 73, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,
+108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 73, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0,
+ 73, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,110,101,119, 95,105,109, 97,103,
+101, 0, 63, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 0,
+ 0, 0, 24, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua51/im_image_le64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_process.loh b/im/src/lua5/loh/im_process.loh
new file mode 100755
index 0000000..47dc66e
--- /dev/null
+++ b/im/src/lua5/loh/im_process.loh
@@ -0,0 +1,817 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_process51/im_process.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_process51/im_process.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 4, 4, 8, 0, 21, 0, 0, 0, 64,108,117, 97,
+ 53, 47,105,109, 95,112,114,111, 99,101,115,115, 46,108,117, 97, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 13,144, 1, 0, 0, 36, 0, 0, 0,100, 64, 0,
+ 0,164,128, 0, 0,228,192, 0, 0, 36, 1, 1, 0,100, 65, 1, 0,128, 1, 0,
+ 0,193, 1, 0, 0, 3, 2, 0, 5,197, 66, 0, 0,198,130,192, 5,156, 65, 0,
+ 3,128, 1, 0, 0,193,193, 0, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 1,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 1, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 1, 0, 1,194, 1, 0, 64, 2,128, 2,133, 66, 0, 0,134, 2, 66,
+ 5,197, 66, 0, 0,198, 66,194, 5,156, 65, 0, 3,128, 1, 0, 0,193,129, 2,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 2, 0, 3, 2, 0, 5,197, 66, 0,
+ 0,198, 2,195, 5,156, 65, 0, 3,128, 1, 0, 0,193, 65, 3, 0, 3, 2,128,
+ 4,133, 66, 0, 0,134,130, 67, 5,195, 2,128, 5,156, 65, 0, 3,133, 65, 0,
+ 0,228,129, 1, 0,137,193,129,135,133, 65, 0, 0,228,193, 1, 0,137,193, 1,
+136,128, 1, 0, 0,193, 65, 4, 0, 36, 2, 2, 0,100, 66, 2, 0,156, 65, 0,
+ 2,133, 65, 0, 0,228,129, 2, 0,137,193, 1,137,128, 1,128, 0,193,193, 4,
+ 0,156, 65, 0, 1,133, 65, 0, 0,228,193, 2, 0,137,193, 1,138,133, 65, 0,
+ 0,228, 1, 3, 0,137,193,129,138,128, 1, 0, 0,193,129, 5, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 5, 0, 36, 66, 3, 0,100,130, 3, 0,156, 65, 0,
+ 2,128, 1, 0, 0,193, 1, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 6,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 6, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 7, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 65, 7, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 7,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 7, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 8, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 8,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 9, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 65, 9, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 9, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 9, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 10,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 10, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 10, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 10, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 1, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 11,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 11, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 12, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 65, 12, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 12,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 12, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 13, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 13, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 13, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 13,
+ 0,156, 65, 0, 1,128, 1,128, 1,193, 1, 14, 0, 3, 2, 0, 4,100,194, 3,
+ 0,156, 65, 0, 2,133, 65, 0, 0,228, 1, 4, 0,137,193,129,156,164, 65, 4,
+ 0,192, 1, 0, 0, 1,130, 14, 0, 67, 2,128, 5, 0, 3, 0, 3,220, 65, 0,
+ 3,192, 1, 0, 0, 1,194, 14, 0, 67, 2,128, 5, 0, 3, 0, 3,220, 65, 0,
+ 3,192, 1, 0, 0, 1, 2, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 15,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 15, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1,194, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 16, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 66, 16, 0,220, 65, 0, 1,192, 1,128, 0, 1,130, 16,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 16, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 2, 17, 0,220, 65, 0, 1,192, 1,128, 0, 1, 66, 17, 0,220, 65, 0,
+ 1,197, 65, 0, 0, 36,130, 4, 0,201, 1, 2,163,192, 1,128, 0, 1,194, 17,
+ 0,220, 65, 0, 1,192, 1, 0, 1, 1, 2, 18, 0,220, 65, 0, 1,192, 1,128,
+ 1, 1, 66, 18, 0,220, 65, 0, 1,192, 1,128, 0, 1,130, 18, 0, 67, 2,128,
+ 5, 5, 67, 0, 0, 6,195, 82, 6,220, 65, 0, 3,197, 65, 0, 0, 36,194, 4,
+ 0,201, 1, 2,166,197, 65, 0, 0, 36, 2, 5, 0,201, 1,130,166,192, 1,128,
+ 0, 1,130, 19, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 19, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 2, 20, 0, 67, 2, 0, 5,197, 66, 0, 0,198, 66,212,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,130, 20, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,194, 20, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 21,
+ 0,220, 65, 0, 1,197, 65, 0, 0, 36, 66, 5, 0,201, 1,130,170,192, 1, 0,
+ 2, 1,130, 21, 0, 67, 2, 0, 5,197, 66, 0, 0,198, 2,194, 5, 5, 67, 0,
+ 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0, 1, 1,194, 21, 0, 67, 2, 0,
+ 5,197, 66, 0, 0,198, 2,214, 5, 5, 67, 0, 0, 6, 67, 86, 6,220, 65, 0,
+ 3,197, 65, 0, 0, 36,130, 5, 0,201, 1, 2,173,197, 65, 0, 0, 36,194, 5,
+ 0,201, 1,130,173,192, 1, 0, 0, 1, 2, 23, 0, 67, 2,128, 5, 5, 67, 0,
+ 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 23, 0,220, 65, 0,
+ 1,192, 1,128, 0, 1,130, 23, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 23,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 24, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 66, 24, 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 24, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,194, 24, 0, 67, 2,128, 5, 5, 67, 0, 0, 6, 67, 86,
+ 6,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 25, 0, 67, 2,128, 5, 5, 67, 0,
+ 0, 6, 67, 86, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 25, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,130, 25, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,194, 25, 0, 67, 2, 0,
+ 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1, 2, 26, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0,
+ 6,220, 65, 0, 3,192, 1,128, 0, 1, 66, 26, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1,130, 26, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0,
+ 6,220, 65, 0, 3,192, 1, 0, 0, 1,194, 26, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 27,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 27, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1,130, 27, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 27, 0, 67, 2, 0,
+ 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1, 2, 28, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0,
+ 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 28, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1,130, 28, 0,220, 65, 0, 1, 30, 0,128, 0,115, 0, 0, 0, 4, 19, 0,
+ 0, 0, 65,110, 97,108,121,122,101, 70,105,110,100, 82,101,103,105,111,110,115,
+ 0, 4, 3, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 85, 83, 72, 79, 82, 84,
+ 0, 4, 21, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114,105,109,101,116,
+101,114, 76,105,110,101, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115, 82,
+101,109,111,118,101, 66,121, 65,114,101, 97, 0, 4, 17, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 70,105,108,108, 72,111,108,101,115, 0, 4, 18, 0, 0, 0, 80,
+114,111, 99,101,115,115, 72,111,117,103,104, 76,105,110,101,115, 0, 3, 0, 0,
+ 0, 0, 0,128,102, 64, 4, 5, 0, 0, 0, 71, 82, 65, 89, 0, 4, 4, 0, 0,
+ 0, 73, 78, 84, 0, 4, 22, 0, 0, 0, 80,114,111, 99,101,115,115, 72,111,117,
+103,104, 76,105,110,101,115, 68,114, 97,119, 0, 4, 25, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 68,105,115,116, 97,110, 99,101, 84,114, 97,110,115,102,111,114,
+109, 0, 4, 6, 0, 0, 0, 70, 76, 79, 65, 84, 0, 4, 23, 0, 0, 0, 80,114,
+111, 99,101,115,115, 82,101,103,105,111,110, 97,108, 77, 97,120,105,109,117,109,
+ 0, 4, 7, 0, 0, 0, 66, 73, 78, 65, 82, 89, 0, 4, 17, 0, 0, 0, 80,114,
+111, 99,101,115,115, 82,101,100,117, 99,101, 78,101,119, 0, 4, 17, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 82,101,115,105,122,101, 78,101,119, 0, 4, 17, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 82,101,100,117, 99,101, 66,121, 52, 0, 4,
+ 15, 0, 0, 0, 80,114,111, 99,101,115,115, 67,114,111,112, 78,101,119, 0, 4,
+ 14, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,115,101,114,116, 0, 4, 21,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 65,100,100, 77, 97,114,103,105,110,115,
+ 78,101,119, 0, 4, 17, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,116, 97,
+116,101, 78,101,119, 0, 4, 17, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,
+116, 97,116,101, 82,101,102, 0, 4, 16, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 82,111,116, 97,116,101, 57, 48, 0, 4, 17, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,111,116, 97,116,101, 49, 56, 48, 0, 4, 14, 0, 0, 0, 80,114,111, 99,
+101,115,115, 77,105,114,114,111,114, 0, 4, 12, 0, 0, 0, 80,114,111, 99,101,
+115,115, 70,108,105,112, 0, 4, 14, 0, 0, 0, 80,114,111, 99,101,115,115, 82,
+ 97,100,105, 97,108, 0, 4, 25, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114,
+ 97,121, 77,111,114,112,104, 67,111,110,118,111,108,118,101, 0, 4, 22, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 69,114,111,
+100,101, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,
+111,114,112,104, 68,105,108, 97,116,101, 0, 4, 21, 0, 0, 0, 80,114,111, 99,
+101,115,115, 71,114, 97,121, 77,111,114,112,104, 79,112,101,110, 0, 4, 22, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 67,108,
+111,115,101, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121,
+ 77,111,114,112,104, 84,111,112, 72, 97,116, 0, 4, 21, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 87,101,108,108, 0, 4, 25,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 71,
+114, 97,100,105,101,110,116, 0, 4, 24, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 66,105,110, 77,111,114,112,104, 67,111,110,118,111,108,118,101, 0, 4, 21, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 69,114,111,
+100,101, 0, 4, 22, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,
+114,112,104, 68,105,108, 97,116,101, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,
+115,115, 66,105,110, 77,111,114,112,104, 79,112,101,110, 0, 4, 21, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,108,111,115,101,
+ 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,
+104, 79,117,116,108,105,110,101, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,
+115, 66,105,110, 77,111,114,112,104, 84,104,105,110, 0, 4, 22, 0, 0, 0, 80,
+114,111, 99,101,115,115, 77,101,100,105, 97,110, 67,111,110,118,111,108,118,101,
+ 0, 4, 21, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,111,
+110,118,111,108,118,101, 0, 4, 27, 0, 0, 0, 80,114,111, 99,101,115,115, 82,
+ 97,110,107, 67,108,111,115,101,115,116, 67,111,110,118,111,108,118,101, 0, 4,
+ 23, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,107, 77, 97,120, 67,111,
+110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 82,
+ 97,110,107, 77,105,110, 67,111,110,118,111,108,118,101, 0, 4, 16, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101, 0, 4, 19, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101, 83,101,112, 0,
+ 4, 19, 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101,
+ 82,101,112, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,110,118,
+111,108,118,101, 68,117, 97,108, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,
+115, 67,111,109,112, 97,115,115, 67,111,110,118,111,108,118,101, 0, 4, 20, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 77,101, 97,110, 67,111,110,118,111,108,118,
+101, 0, 4, 24, 0, 0, 0, 80,114,111, 99,101,115,115, 71, 97,117,115,115,105,
+ 97,110, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 80,114,111, 99,
+101,115,115, 66, 97,114,108,101,116,116, 67,111,110,118,111,108,118,101, 0, 4,
+ 22, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,116,101,114,108, 97, 99,101,
+ 83,112,108,105,116, 0, 4, 25, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,
+116,101,114,108, 97, 99,101, 83,112,108,105,116, 78,101,119, 0, 4, 30, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 68,105,102,102, 79,102, 71, 97,117,115,115,105,
+ 97,110, 67,111,110,118,111,108,118,101, 0, 4, 29, 0, 0, 0, 80,114,111, 99,
+101,115,115, 76, 97,112, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,110,118,
+111,108,118,101, 0, 4, 21, 0, 0, 0, 80,114,111, 99,101,115,115, 83,111, 98,
+101,108, 67,111,110,118,111,108,118,101, 0, 4, 26, 0, 0, 0, 80,114,111, 99,
+101,115,115, 83,112,108,105,110,101, 69,100,103,101, 67,111,110,118,111,108,118,
+101, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 80,114,101,119,105,116,
+116, 67,111,110,118,111,108,118,101, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,
+115,115, 90,101,114,111, 67,114,111,115,115,105,110,103, 0, 4, 13, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 67, 97,110,110,121, 0, 4, 22, 0, 0, 0, 80,114,
+111, 99,101,115,115, 85,110, 65,114,105,116,104,109,101,116,105, 99, 79,112, 0,
+ 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115, 65,114,105,116,104,109,101,116,
+105, 99, 79,112, 0, 4, 15, 0, 0, 0, 80,114,111, 99,101,115,115, 85,110,115,
+104, 97,114,112, 0, 4, 13, 0, 0, 0, 80,114,111, 99,101,115,115, 83,104, 97,
+114,112, 0, 4, 19, 0, 0, 0, 80,114,111, 99,101,115,115, 83,104, 97,114,112,
+ 75,101,114,110,101,108, 0, 4, 28, 0, 0, 0, 80,114,111, 99,101,115,115, 65,
+114,105,116,104,109,101,116,105, 99, 67,111,110,115,116, 79,112, 78,101,119, 0,
+ 4, 18, 0, 0, 0, 80,114,111, 99,101,115,115, 66,108,101,110,100, 67,111,110,
+115,116, 0, 4, 13, 0, 0, 0, 80,114,111, 99,101,115,115, 66,108,101,110,100,
+ 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,
+109,112,108,101,120, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115, 77,101,
+114,103,101, 67,111,109,112,108,101,120, 0, 4, 7, 0, 0, 0, 67, 70, 76, 79,
+ 65, 84, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 77,117,108,116,105,
+112,108,101, 77,101, 97,110, 78,101,119, 0, 4, 25, 0, 0, 0, 80,114,111, 99,
+101,115,115, 77,117,108,116,105,112,108,101, 83,116,100, 68,101,118, 78,101,119,
+ 0, 4, 22, 0, 0, 0, 80,114,111, 99,101,115,115, 65,117,116,111, 67,111,118,
+ 97,114,105, 97,110, 99,101, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 77,117,108,116,105,112,108,121, 67,111,110,106, 0, 4, 26, 0, 0, 0, 80,114,
+111, 99,101,115,115, 81,117, 97,110,116,105,122,101, 82, 71, 66, 85,110,105,102,
+111,114,109, 0, 4, 4, 0, 0, 0, 77, 65, 80, 0, 4, 27, 0, 0, 0, 80,114,
+111, 99,101,115,115, 81,117, 97,110,116,105,122,101, 71,114, 97,121, 85,110,105,
+102,111,114,109, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 69,120,112,
+ 97,110,100, 72,105,115,116,111,103,114, 97,109, 0, 4, 25, 0, 0, 0, 80,114,
+111, 99,101,115,115, 69,113,117, 97,108,105,122,101, 72,105,115,116,111,103,114,
+ 97,109, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116,
+ 89, 67,104,114,111,109, 97, 78,101,119, 0, 4, 16, 0, 0, 0, 80,114,111, 99,
+101,115,115, 83,112,108,105,116, 72, 83, 73, 0, 4, 16, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 77,101,114,103,101, 72, 83, 73, 0, 4, 4, 0, 0, 0, 82, 71,
+ 66, 0, 4, 5, 0, 0, 0, 66, 89, 84, 69, 0, 4, 26, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 83,112,108,105,116, 67,111,109,112,111,110,101,110,116,115, 78,
+101,119, 0, 4, 26, 0, 0, 0, 80,114,111, 99,101,115,115, 77,101,114,103,101,
+ 67,111,109,112,111,110,101,110,116,115, 78,101,119, 0, 4, 27, 0, 0, 0, 80,
+114,111, 99,101,115,115, 78,111,114,109, 97,108,105,122,101, 67,111,109,112,111,
+110,101,110,116,115, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,
+112,108, 97, 99,101, 67,111,108,111,114, 0, 4, 17, 0, 0, 0, 80,114,111, 99,
+101,115,115, 66,105,116,119,105,115,101, 79,112, 0, 4, 18, 0, 0, 0, 80,114,
+111, 99,101,115,115, 66,105,116,119,105,115,101, 78,111,116, 0, 4, 15, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 66,105,116, 77, 97,115,107, 0, 4, 16, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 66,105,116, 80,108, 97,110,101, 0, 4, 17, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 84,111,110,101, 71, 97,109,117,116, 0, 4,
+ 19, 0, 0, 0, 80,114,111, 99,101,115,115, 85,110, 78,111,114,109, 97,108,105,
+122,101, 0, 4, 18, 0, 0, 0, 80,114,111, 99,101,115,115, 68,105,114,101, 99,
+116, 67,111,110,118, 0, 4, 16, 0, 0, 0, 80,114,111, 99,101,115,115, 78,101,
+103, 97,116,105,118,101, 0, 4, 30, 0, 0, 0, 80,114,111, 99,101,115,115, 82,
+ 97,110,103,101, 67,111,110,116,114, 97,115,116, 84,104,114,101,115,104,111,108,
+100, 0, 4, 25, 0, 0, 0, 80,114,111, 99,101,115,115, 76,111, 99, 97,108, 77,
+ 97,120, 84,104,114,101,115,104,111,108,100, 0, 4, 17, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 84,104,114,101,115,104,111,108,100, 0, 4, 23, 0, 0, 0, 80,
+114,111, 99,101,115,115, 84,104,114,101,115,104,111,108,100, 66,121, 68,105,102,
+102, 0, 4, 27, 0, 0, 0, 80,114,111, 99,101,115,115, 72,121,115,116,101,114,
+101,115,105,115, 84,104,114,101,115,104,111,108,100, 0, 4, 27, 0, 0, 0, 80,
+114,111, 99,101,115,115, 85,110,105,102,111,114,109, 69,114,114, 84,104,114,101,
+115,104,111,108,100, 0, 4, 28, 0, 0, 0, 80,114,111, 99,101,115,115, 68,105,
+102,117,115,105,111,110, 69,114,114, 84,104,114,101,115,104,111,108,100, 0, 4,
+ 24, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114, 99,101,110,116, 84,104,
+114,101,115,104,111,108,100, 0, 4, 21, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 79,116,115,117, 84,104,114,101,115,104,111,108,100, 0, 4, 23, 0, 0, 0, 80,
+114,111, 99,101,115,115, 77,105,110, 77, 97,120, 84,104,114,101,115,104,111,108,
+100, 0, 4, 22, 0, 0, 0, 80,114,111, 99,101,115,115, 83,108,105, 99,101, 84,
+104,114,101,115,104,111,108,100, 0, 4, 16, 0, 0, 0, 80,114,111, 99,101,115,
+115, 80,105,120,101,108, 97,116,101, 0, 4, 17, 0, 0, 0, 80,114,111, 99,101,
+115,115, 80,111,115,116,101,114,105,122,101, 0, 24, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 25, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0,
+ 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,
+192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0,
+ 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3,
+ 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 78,101,119, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 5, 1, 7, 8, 23, 0, 0,
+ 0,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128,
+ 0,132, 1, 0, 1,196, 1,128, 1,156,128, 0, 3,196, 0, 0, 2, 0, 1, 0,
+ 0, 64, 1, 0, 1,133,129, 0, 0,192, 1,128, 0,156, 1, 0, 1,220,128, 0,
+ 0,218, 0, 0, 0, 22,192, 0,128, 0, 1,128, 1, 64, 1, 0, 1, 30, 1,128,
+ 1, 22, 0, 0,128,158, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0,
+ 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 23, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 18,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18,
+ 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 20,
+ 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 4,
+ 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0,
+ 0, 22, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 22, 0, 0,
+ 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 22,
+ 0, 0, 0, 4, 0, 0, 0,114,101,116, 0, 15, 0, 0, 0, 22, 0, 0, 0, 5,
+ 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0, 0,104,101,105,
+103,104,116, 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0,
+ 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0,102,117,
+110, 99, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10,
+ 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 9,
+ 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 6, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0,
+ 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0,
+ 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 5, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 50, 0, 0, 0, 0, 5, 0, 11,
+ 22, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,
+ 5,130, 0, 0, 6,194, 64, 4, 65, 2, 1, 0,128, 2, 0, 0, 28, 2,128, 1,
+156, 65, 0, 0,133, 1, 0, 0,192, 1, 0, 0, 1, 66, 1, 0,213, 1,130, 3,
+ 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2,
+ 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0,
+ 0,105,109, 0, 4, 7, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 7, 0, 0,
+ 0,115,116,114,105,110,103, 0, 4, 7, 0, 0, 0,102,111,114,109, 97,116, 0,
+ 4, 24, 0, 0, 0,117,110,100,101,102,105,110,101,100, 32,102,117,110, 99,116,
+105,111,110, 32, 96, 37,115, 39, 0, 4, 4, 0, 0, 0, 78,101,119, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 5, 2, 7, 10, 24, 0,
+ 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1, 0, 0,132, 1,
+128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1, 0, 2, 64, 1,
+ 0, 0,128, 1,128, 0,192, 1,128, 1, 5,130, 0, 0, 64, 2, 0, 1, 28, 2,
+ 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22,192, 0,128, 64, 1, 0, 2,128, 1,
+128, 1, 94, 1,128, 1, 22, 0, 0,128,222, 0, 0, 1, 30, 0,128, 0, 3, 0,
+ 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101,
+ 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,117,110,112,
+ 97, 99,107, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 44, 0, 0, 0,
+ 44, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0,
+ 47, 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0, 11, 0, 0, 0,115,114, 99, 95,
+105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 23, 0, 0, 0, 11, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 0, 23, 0, 0, 0, 4, 0,
+ 0, 0, 97,114,103, 0, 0, 0, 0, 0, 23, 0, 0, 0, 10, 0, 0, 0,100,115,
+116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 23, 0, 0, 0, 4, 0, 0, 0,
+114,101,116, 0, 16, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0,
+119,105,100,116,104, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0,
+ 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0,100, 97,116,
+ 97, 95,116,121,112,101, 0, 5, 0, 0, 0,102,117,110, 99, 0, 22, 0, 0, 0,
+ 32, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0,
+ 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 49, 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0,102,117,110, 99,
+110, 97,109,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 6, 0, 0, 0,119,105,100,
+116,104, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0,104,101,105,103,104,
+116, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0, 0, 0, 99,111,108,111,114, 95,
+115,112, 97, 99,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 10, 0, 0, 0,100, 97,
+116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0,
+102,117,110, 99, 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 56, 0, 0, 0, 73, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0,
+ 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0,
+ 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128,
+ 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130,
+ 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 7, 0,
+ 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 78,101,119, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 72, 0, 0, 0, 5, 3, 7, 12, 25, 0,
+ 0, 0, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0, 0,196, 1,
+128, 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0, 2,128, 1,
+ 0, 0,192, 1,128, 0, 0, 2, 0, 1, 64, 2, 0, 2,133,130, 0, 0,192, 2,
+128, 1,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22,192, 0,128,128, 1,
+128, 2,192, 1, 0, 2,158, 1,128, 1, 22, 0, 0,128, 30, 1, 0, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,
+109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0,
+ 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 25, 0, 0, 0, 63, 0, 0, 0,
+ 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
+ 63, 0, 0, 0, 63, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0,
+ 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0,
+ 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0,
+ 68, 0, 0, 0, 68, 0, 0, 0, 70, 0, 0, 0, 72, 0, 0, 0, 6, 0, 0, 0,
+ 11, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 24,
+ 0, 0, 0, 11, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0,
+ 0, 0, 24, 0, 0, 0, 11, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 51,
+ 0, 0, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0,
+ 0, 24, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8,
+ 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0,114,101,116, 0, 17, 0, 0, 0, 24,
+ 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0,
+ 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0,
+ 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 58,
+ 0, 0, 0, 58, 0, 0, 0, 58, 0, 0, 0, 61, 0, 0, 0, 61, 0, 0, 0, 61,
+ 0, 0, 0, 61, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72,
+ 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 73, 0, 0, 0, 6,
+ 0, 0, 0, 9, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 16, 0,
+ 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 97, 0, 0, 0,
+ 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,
+192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,
+213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1,
+ 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0,
+ 4, 3, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 97,115,115,101,114,116, 0,
+ 4, 4, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0,
+ 0, 96, 0, 0, 0, 5, 1, 7, 10, 35, 0, 0, 0,133, 0, 0, 0,134, 64, 64,
+ 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0, 1,196, 1,128,
+ 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1, 0,
+ 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1, 0,
+ 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1, 5,130, 0, 0, 64, 2,128,
+ 0, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22, 0, 1,128, 64, 1, 0,
+ 2,128, 1, 0, 1,192, 1,128, 1, 94, 1, 0, 2, 22,128, 0,128, 64, 1, 0,
+ 1,128, 1,128, 1, 94, 1,128, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0,
+ 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86,
+ 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 87,
+ 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87,
+ 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90,
+ 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90,
+ 0, 0, 0, 91, 0, 0, 0, 91, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92,
+ 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 94, 0, 0, 0, 94, 0, 0, 0, 94,
+ 0, 0, 0, 96, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 97,114,103,
+ 0, 0, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0,100,115,116, 95,105,109, 97,
+103,101, 49, 0, 8, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0,100,115,116, 95,
+105,109, 97,103,101, 50, 0, 16, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0,114,
+101,116, 0, 24, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0,119,
+105,100,116,104, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0,100, 97,116, 97,
+ 95,116,121,112,101, 0, 5, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 80,
+ 0, 0, 0, 80, 0, 0, 0, 81, 0, 0, 0, 81, 0, 0, 0, 81, 0, 0, 0, 84,
+ 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 96, 0, 0, 0, 96,
+ 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96,
+ 0, 0, 0, 97, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0,102,117,110, 99,110,
+ 97,109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,
+104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,
+112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0, 0,100, 97,116,
+ 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0,102,
+117,110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+103, 0, 0, 0,122, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0,
+ 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,
+192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0,
+ 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3,
+ 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 78,101,119, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,108, 0, 0, 0,121, 0, 0, 0, 5, 1, 7, 12, 46, 0, 0,
+ 0,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128,
+ 0,132, 1, 0, 1,196, 1,128, 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192,
+ 1, 0, 1, 0, 0, 68, 1, 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128,
+ 1,220,128, 0, 3, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0,
+ 0,196, 1,128, 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0,
+ 2,128, 1, 0, 0,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,133,130, 0,
+ 0,192, 2,128, 0,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22, 64, 1,
+128,128, 1,128, 2,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,158, 1,128,
+ 2, 22,192, 0,128,128, 1, 0, 1,192, 1,128, 1, 0, 2, 0, 2,158, 1, 0,
+ 2, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0,
+ 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4,
+ 7, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 46, 0, 0, 0,110,
+ 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110,
+ 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111,
+ 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111,
+ 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112,
+ 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,115, 0, 0, 0,115,
+ 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115,
+ 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,116, 0, 0, 0,117,
+ 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117,
+ 0, 0, 0,119, 0, 0, 0,119, 0, 0, 0,119, 0, 0, 0,119, 0, 0, 0,121,
+ 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 45, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0,
+ 0, 45, 0, 0, 0, 11, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 49, 0,
+ 8, 0, 0, 0, 45, 0, 0, 0, 11, 0, 0, 0,100,115,116, 95,105,109, 97,103,
+101, 50, 0, 16, 0, 0, 0, 45, 0, 0, 0, 11, 0, 0, 0,100,115,116, 95,105,
+109, 97,103,101, 51, 0, 24, 0, 0, 0, 45, 0, 0, 0, 4, 0, 0, 0,114,101,
+116, 0, 33, 0, 0, 0, 45, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0,119,105,
+100,116,104, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 99,
+111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0,100, 97,116, 97, 95,
+116,121,112,101, 0, 5, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0,104, 0,
+ 0, 0,104, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,108, 0,
+ 0, 0,108, 0, 0, 0,108, 0, 0, 0,108, 0, 0, 0,121, 0, 0, 0,121, 0,
+ 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0,
+ 0, 0,122, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0,102,117,110, 99,110, 97,
+109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0, 0,100, 97,116, 97,
+ 95,116,121,112,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0,102,117,
+110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126,
+ 0, 0, 0,130, 0, 0, 0, 0, 1, 0, 7, 18, 0, 0, 0,100, 0, 0, 0,133,
+ 0, 0, 0,134, 64, 64, 1,192, 0,128, 0, 11,129, 64, 0, 28, 1, 0, 1,220,
+128, 0, 0, 0, 1,128, 0, 75,193, 64, 0, 92, 1, 0, 1, 28,129, 0, 0,204,
+ 0,129, 1,156,128, 0, 1,143, 0, 65, 1,206,128, 0,130,204, 64,193, 1,222,
+ 0, 0, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 5, 0, 0, 0,109, 97,116,104,
+ 0, 4, 5, 0, 0, 0,115,113,114,116, 0, 4, 6, 0, 0, 0, 87,105,100,116,
+104, 0, 4, 7, 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 64, 3, 0, 0, 0, 0, 0, 0,240, 63, 1, 0, 0, 0, 0, 0, 0, 0,
+127, 0, 0, 0,127, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 78, 0, 0, 0,
+ 94, 0, 0, 1, 30, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+127, 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0,
+120, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0,127, 0,
+ 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0,
+ 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0,
+ 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,129, 0, 0, 0,129, 0,
+ 0, 0,129, 0, 0, 0,130, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 17, 0, 0, 0, 4, 0, 0, 0,115,113,114, 0,
+ 1, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0,114,109, 97,120, 0, 14, 0, 0,
+ 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,141, 0, 0, 0,144, 0, 0,
+ 0, 0, 3, 0, 7, 14, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0,
+ 0, 64, 1,128, 0,128, 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0, 6,129, 64,
+ 2, 64, 1, 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30, 1,128,
+ 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0,
+ 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4,
+ 14, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,100,117, 99,101, 0, 0, 0,
+ 0, 0, 14, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0,
+ 0, 0,142, 0, 0, 0,142, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0,
+ 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,144, 0,
+ 0, 0, 4, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0,
+ 0, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 13, 0, 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0,
+ 0, 13, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 6,
+ 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,146, 0, 0, 0,149,
+ 0, 0, 0, 0, 3, 0, 7, 14, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0,
+ 1, 0, 0, 64, 1,128, 0,128, 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0, 6,
+129, 64, 2, 64, 1, 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30,
+ 1,128, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4,
+ 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 14, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,115,105,122,101, 0,
+ 0, 0, 0, 0, 14, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,
+147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,
+148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,
+149, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,
+101, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0,
+ 0, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 0,
+ 0, 0, 0, 13, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101,
+ 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,151, 0, 0,
+ 0,151, 0, 0, 0, 0, 1, 0, 3, 5, 0, 0, 0, 75, 0, 64, 0, 92,128, 0,
+ 1, 79, 64,192, 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 6, 0,
+ 0, 0, 87,105,100,116,104, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0,
+ 0, 5, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0,
+ 0,151, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,105,109, 97,103,101, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 0, 0, 0,152,
+ 0, 0, 0, 0, 1, 0, 3, 5, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1, 79,
+ 64,192, 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0, 0,
+ 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0,
+ 5, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,
+152, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,105,109, 97,103,101, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 0, 0, 0,160, 0,
+ 0, 0, 0, 5, 0, 13, 19, 0, 0, 0, 77, 65, 0, 1, 76, 1,192, 2,141,193,
+ 0, 2,140, 1, 64, 3,197, 65, 0, 0,198,129,192, 3, 0, 2, 0, 0, 64, 2,
+128, 2,128, 2, 0, 3,220,129, 0, 2, 5, 66, 0, 0, 6,194, 64, 4, 64, 2,
+ 0, 0,128, 2,128, 3,192, 2,128, 0, 0, 3,128, 1, 28, 66,128, 2,222, 1,
+ 0, 1, 30, 0,128, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4,
+ 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 4, 12, 0, 0, 0, 80,114,111, 99,101,115,
+115, 67,114,111,112, 0, 0, 0, 0, 0, 19, 0, 0, 0,155, 0, 0, 0,155, 0,
+ 0, 0,156, 0, 0, 0,156, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0,
+ 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0,158, 0,
+ 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0,
+ 0, 0,159, 0, 0, 0,160, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,
+120,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,120,109, 97,
+120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,121,109,105,110, 0, 0,
+ 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,121,109, 97,120, 0, 0, 0, 0, 0,
+ 18, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 2, 0, 0, 0, 18, 0,
+ 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 4, 0, 0, 0, 18, 0, 0,
+ 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 10, 0, 0, 0, 18,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0, 0,
+ 5, 0, 13, 19, 0, 0, 0, 77, 65, 0, 1, 76, 1,192, 2,141,193, 0, 2,140,
+ 1, 64, 3,197, 65, 0, 0,198,129,192, 3, 0, 2, 0, 0, 64, 2,128, 2,128,
+ 2, 0, 3,220,129, 0, 2, 5, 66, 0, 0, 6,194, 64, 4, 64, 2, 0, 0,128,
+ 2,128, 3,192, 2,128, 0, 0, 3,128, 1, 28, 66,128, 2,222, 1, 0, 1, 30,
+ 0,128, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0,
+ 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101,
+ 66, 97,115,101,100, 0, 4, 18, 0, 0, 0, 80,114,111, 99,101,115,115, 65,100,
+100, 77, 97,114,103,105,110,115, 0, 0, 0, 0, 0, 19, 0, 0, 0,165, 0, 0,
+ 0,165, 0, 0, 0,166, 0, 0, 0,166, 0, 0, 0,167, 0, 0, 0,167, 0, 0,
+ 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,168, 0, 0,
+ 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0,
+ 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0,
+ 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,
+ 0, 0, 0,120,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,
+120,109, 97,120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,121,109,105,
+110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,121,109, 97,120, 0, 0,
+ 0, 0, 0, 18, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 2, 0, 0,
+ 0, 18, 0, 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 4, 0, 0, 0,
+ 18, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 10, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0,176, 0,
+ 0, 0, 0, 4, 0, 13, 26, 0, 0, 0, 5, 1, 0, 0, 6, 65, 64, 2, 75,129,
+ 64, 0, 92,129, 0, 1,139,193, 64, 0,156,129, 0, 1,192, 1,128, 0, 0, 2,
+ 0, 1, 28,193,128, 2,133, 1, 0, 0,134, 1, 65, 3,192, 1, 0, 0, 0, 2,
+ 0, 2, 64, 2,128, 2,156,129, 0, 2,197, 1, 0, 0,198, 65,193, 3, 0, 2,
+ 0, 0, 64, 2, 0, 3,128, 2,128, 0,192, 2, 0, 1, 0, 3,128, 1,220,129,
+ 0, 3, 0, 2, 0, 3,222, 1,128, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 3,
+ 0, 0, 0,105,109, 0, 4, 22, 0, 0, 0, 80,114,111, 99,101,115,115, 67, 97,
+108, 99, 82,111,116, 97,116,101, 83,105,122,101, 0, 4, 6, 0, 0, 0, 87,105,
+100,116,104, 0, 4, 7, 0, 0, 0, 72,101,105,103,104,116, 0, 4, 17, 0, 0,
+ 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 14,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,116, 97,116,101, 0, 0, 0, 0,
+ 0, 26, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0,
+ 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0,
+ 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0,
+ 0,174, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0,
+ 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0,
+ 0,175, 0, 0, 0,176, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0,115,114, 99,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 99,
+111,115, 48, 0, 0, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0,115,105,110, 48,
+ 0, 0, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0,111,114,100,101,114, 0, 0,
+ 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0,119,105,100,116,104, 0, 9, 0, 0,
+ 0, 25, 0, 0, 0, 7, 0, 0, 0,104,101,105,103,104,116, 0, 9, 0, 0, 0,
+ 25, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 15, 0,
+ 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0, 0, 1, 0, 3, 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0, 1, 94, 0,
+ 0, 0, 30, 0,128, 0, 1, 0, 0, 0, 4, 7, 0, 0, 0, 72,101,105,103,104,
+116, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,105,109, 97,103,101, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0, 0,
+179, 0, 0, 0, 0, 1, 0, 3, 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0, 1,
+ 94, 0, 0, 0, 30, 0,128, 0, 1, 0, 0, 0, 4, 6, 0, 0, 0, 87,105,100,
+116,104, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179,
+ 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,212, 0, 0,
+ 0,212, 0, 0, 0, 0, 1, 0, 3, 13, 0, 0, 0, 75, 0, 64, 0, 92,128, 0,
+ 1, 90, 0, 0, 0, 22,192, 0,128, 75, 0, 64, 0, 93, 0, 0, 1, 94, 0, 0,
+ 0, 22,192, 0,128, 75, 0, 64, 0, 92,128, 0, 1, 79, 64,192, 0, 94, 0, 0,
+ 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0, 0, 72,101,105,103,104,116,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 13, 0, 0, 0,212, 0,
+ 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0,
+ 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0,
+ 0, 0,212, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+214, 0, 0, 0,227, 0, 0, 0, 0, 1, 0, 8, 36, 0, 0, 0, 75, 0, 64, 0,
+ 92,128, 0, 1, 79, 64,192, 0,133,128, 0, 0,134,192, 64, 1,203, 0, 64, 0,
+220,128, 0, 1, 1, 65, 0, 0,156,128,128, 1,154, 0, 0, 0, 22, 0, 0,128,
+ 76, 0,193, 0,133, 64, 1, 0,134,128, 65, 1,192, 0, 0, 0, 3, 1, 0, 2,
+ 64, 1,128, 0,156,128, 0, 2,197, 64, 1, 0,198,128,193, 1, 0, 1, 0, 0,
+ 67, 1,128, 2,139, 1, 64, 0,156,129, 0, 1,143, 65, 64, 3,220,128, 0, 2,
+ 5, 65, 1, 0, 6,193, 65, 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1,
+ 28, 65, 0, 2, 0, 1, 0, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,128, 0,
+ 8, 0, 0, 0, 4, 7, 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 64, 4, 5, 0, 0, 0,109, 97,116,104, 0, 4, 4, 0, 0, 0,
+109,111,100, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0, 0,105,109,
+ 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,
+101,100, 0, 4, 22, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,116,101,114,
+108, 97, 99,101, 83,112,108,105,116, 0, 0, 0, 0, 0, 36, 0, 0, 0,216, 0,
+ 0, 0,216, 0, 0, 0,216, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0,
+ 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0,
+ 0, 0,218, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0,
+ 0, 0,221, 0, 0, 0,221, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0,
+ 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0,
+ 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0,
+ 0, 0,225, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,227, 0,
+ 0, 0, 4, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0,
+ 0, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0,100,115,116, 95,104,101,105,103,
+104,116, 49, 0, 3, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0,100,115,116, 95,
+105,109, 97,103,101, 49, 0, 18, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0,100,
+115,116, 95,105,109, 97,103,101, 50, 0, 26, 0, 0, 0, 35, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,229, 0, 0, 0,235, 0, 0, 0, 0, 1, 0, 3, 14, 0,
+ 0, 0, 75, 0, 64, 0, 92,128, 0, 1,133, 64, 0, 0,134,128, 64, 1, 87,128,
+128, 0, 22,192, 0,128,133, 64, 0, 0,134,192, 64, 1, 23,128,128, 0, 22, 64,
+ 0,128,133, 64, 0, 0, 70, 0, 65, 1, 94, 0, 0, 1, 30, 0,128, 0, 5, 0,
+ 0, 0, 4, 9, 0, 0, 0, 68, 97,116, 97, 84,121,112,101, 0, 4, 3, 0, 0,
+ 0,105,109, 0, 4, 5, 0, 0, 0, 66, 89, 84, 69, 0, 4, 7, 0, 0, 0, 85,
+ 83, 72, 79, 82, 84, 0, 4, 4, 0, 0, 0, 73, 78, 84, 0, 0, 0, 0, 0, 14,
+ 0, 0, 0,230, 0, 0, 0,230, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231,
+ 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231,
+ 0, 0, 0,232, 0, 0, 0,232, 0, 0, 0,234, 0, 0, 0,235, 0, 0, 0, 2,
+ 0, 0, 0, 6, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0, 10, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 2, 0, 0, 0, 13,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0, 0, 0,254, 0, 0, 0, 0,
+ 3, 0, 9, 13, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0,220,
+128, 0, 1, 5, 1, 0, 0, 6,129, 64, 2, 64, 1, 0, 0,128, 1,128, 0,192,
+ 1,128, 1, 0, 2, 0, 1, 28, 65,128, 2,222, 0, 0, 1, 30, 0,128, 0, 3,
+ 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 25, 0, 0, 0, 80,114,
+111, 99,101,115,115, 65,114,105,116,104,109,101,116,105, 99, 67,111,110,115,116,
+ 79,112, 0, 0, 0, 0, 0, 13, 0, 0, 0,251, 0, 0, 0,251, 0, 0, 0,251,
+ 0, 0, 0,251, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252,
+ 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,253, 0, 0, 0,254,
+ 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 12, 0, 0, 0, 10, 0, 0, 0,115,114, 99, 95, 99,111,110,
+115,116, 0, 0, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0,111,112, 0, 0, 0,
+ 0, 0, 12, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0,
+ 4, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0,
+ 9, 1, 0, 0, 0, 2, 0, 6, 11, 0, 0, 0,133, 0, 0, 0,134, 64, 64, 1,
+198,128, 64, 0,156,128, 0, 1,197, 0, 0, 0,198,192,192, 1, 0, 1, 0, 0,
+ 64, 1, 0, 1,220, 64,128, 1,158, 0, 0, 1, 30, 0,128, 0, 4, 0, 0, 0,
+ 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109, 97,103,101, 67,114,
+101, 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4,
+ 20, 0, 0, 0, 80,114,111, 99,101,115,115, 77,117,108,116,105,112,108,101, 77,
+101, 97,110, 0, 0, 0, 0, 0, 11, 0, 0, 0, 6, 1, 0, 0, 6, 1, 0, 0,
+ 6, 1, 0, 0, 6, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0,
+ 7, 1, 0, 0, 7, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 3, 0, 0, 0,
+ 15, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,
+103,101, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,
+ 1, 0, 0, 15, 1, 0, 0, 0, 2, 0, 7, 12, 0, 0, 0,133, 0, 0, 0,134,
+ 64, 64, 1,198,128, 64, 0,156,128, 0, 1,197, 0, 0, 0,198,192,192, 1, 0,
+ 1, 0, 0, 64, 1,128, 0,128, 1, 0, 1,220, 64, 0, 2,158, 0, 0, 1, 30,
+ 0,128, 0, 4, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0,
+ 0, 0, 0, 0,240, 63, 4, 22, 0, 0, 0, 80,114,111, 99,101,115,115, 77,117,
+108,116,105,112,108,101, 83,116,100, 68,101,118, 0, 0, 0, 0, 0, 12, 0, 0,
+ 0, 12, 1, 0, 0, 12, 1, 0, 0, 12, 1, 0, 0, 12, 1, 0, 0, 13, 1, 0,
+ 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0,
+ 0, 14, 1, 0, 0, 15, 1, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0,115,114, 99,
+ 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0, 0, 0, 0, 11, 0, 0, 0,
+ 11, 0, 0, 0,109,101, 97,110, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 11,
+ 0, 0, 0, 10, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 4, 0, 0,
+ 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 29, 1, 0,
+ 0, 0, 1, 0, 8, 28, 0, 0, 0, 69, 0, 0, 0, 70, 64,192, 0,128, 0, 0,
+ 0,195, 0, 0, 2, 69, 1, 0, 0, 70,129,192, 2,133, 1, 0, 0,134,193, 64,
+ 3, 92,128, 0, 3,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 3, 1,128,
+ 2,133, 1, 0, 0,134, 1, 65, 3,197, 1, 0, 0,198,193,192, 3,156,128, 0,
+ 3,197, 0, 0, 0,198, 64,193, 1, 0, 1, 0, 0, 64, 1,128, 0,128, 1, 0,
+ 1,220, 64, 0, 2,192, 0,128, 0, 0, 1, 0, 1,222, 0,128, 1, 30, 0,128,
+ 0, 6, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 73,109,
+ 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 5, 0, 0, 0,
+ 71, 82, 65, 89, 0, 4, 5, 0, 0, 0, 66, 89, 84, 69, 0, 4, 4, 0, 0, 0,
+ 82, 71, 66, 0, 4, 20, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,
+116, 89, 67,104,114,111,109, 97, 0, 0, 0, 0, 0, 28, 0, 0, 0, 25, 1, 0,
+ 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0,
+ 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0,
+ 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0,
+ 0, 26, 1, 0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0,
+ 0, 27, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0,
+ 0, 28, 1, 0, 0, 29, 1, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0,115,114, 99,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 27, 0, 0, 0, 8, 0, 0, 0,121,
+ 95,105,109, 97,103,101, 0, 9, 0, 0, 0, 27, 0, 0, 0, 13, 0, 0, 0, 99,
+104,114,111,109, 97, 95,105,109, 97,103,101, 0, 18, 0, 0, 0, 27, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 34, 1, 0, 0, 42, 1, 0, 0, 0, 1, 0, 14,
+ 29, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1,138, 0, 0, 0,193, 64, 0, 0,
+ 0, 1,128, 0, 65, 65, 0, 0,224,128, 2,128,197,129, 0, 0,198,193,192, 3,
+ 0, 2, 0, 1, 69, 2, 1, 0, 70, 66,193, 4,128, 2, 0, 0,195, 2, 0, 6,
+ 69, 3, 1, 0, 70,131,193, 6, 92, 2,128, 2,220, 65, 0, 0,223,192,252,127,
+197, 0, 1, 0,198,192,193, 1, 0, 1, 0, 0, 64, 1, 0, 1,220, 64,128, 1,
+197, 0, 2, 0, 0, 1, 0, 1,221, 0, 0, 1,222, 0, 0, 0, 30, 0,128, 0,
+ 9, 0, 0, 0, 4, 6, 0, 0, 0, 68,101,112,116,104, 0, 3, 0, 0, 0, 0,
+ 0, 0,240, 63, 4, 6, 0, 0, 0,116, 97, 98,108,101, 0, 4, 7, 0, 0, 0,
+105,110,115,101,114,116, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 5, 0,
+ 0, 0, 71, 82, 65, 89, 0, 4, 23, 0, 0, 0, 80,114,111, 99,101,115,115, 83,
+112,108,105,116, 67,111,109,112,111,110,101,110,116,115, 0, 4, 7, 0, 0, 0,
+117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 29, 0, 0, 0, 35, 1, 0, 0, 35,
+ 1, 0, 0, 36, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37,
+ 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38,
+ 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38,
+ 1, 0, 0, 38, 1, 0, 0, 37, 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 40,
+ 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 41, 1, 0, 0, 41, 1, 0, 0, 41,
+ 1, 0, 0, 41, 1, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0,
+ 0,100,101,112,116,104, 0, 2, 0, 0, 0, 28, 0, 0, 0, 11, 0, 0, 0,100,
+115,116, 95,105,109, 97,103,101,115, 0, 3, 0, 0, 0, 28, 0, 0, 0, 12, 0,
+ 0, 0, 40,102,111,114, 32,105,110,100,101,120, 41, 0, 6, 0, 0, 0, 19, 0,
+ 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,108,105,109,105,116, 41, 0, 6, 0,
+ 0, 0, 19, 0, 0, 0, 11, 0, 0, 0, 40,102,111,114, 32,115,116,101,112, 41,
+ 0, 6, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0,105, 0, 7, 0, 0, 0, 18,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 0,
+ 1, 0, 6, 14, 0, 0, 0, 69, 0, 0, 0, 70, 64,192, 0,134,128, 64, 0,195,
+ 0, 0, 2, 69, 1, 0, 0, 70,193,192, 2, 92,128,128, 2,133, 0, 0, 0,134,
+ 0, 65, 1,192, 0, 0, 0, 0, 1,128, 0,156, 64,128, 1, 94, 0, 0, 1, 30,
+ 0,128, 0, 5, 0, 0, 0, 4, 3, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0,
+ 0, 0, 0, 0,240, 63, 4, 4, 0, 0, 0, 82, 71, 66, 0, 4, 23, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 77,101,114,103,101, 67,111,109,112,111,110,101,110,
+116,115, 0, 0, 0, 0, 0, 14, 0, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45,
+ 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 46,
+ 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 47,
+ 1, 0, 0, 48, 1, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 95,108,105,115,116, 0, 0, 0, 0, 0, 13, 0, 0, 0, 10, 0,
+ 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 7, 0, 0, 0, 13, 0, 0, 0,
+ 0, 0, 0, 0,144, 1, 0, 0, 25, 0, 0, 0, 50, 0, 0, 0, 73, 0, 0, 0,
+ 97, 0, 0, 0,122, 0, 0, 0,130, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,
+132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,133, 0, 0, 0,
+133, 0, 0, 0,133, 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,
+135, 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,
+136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,
+136, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0,137, 0, 0, 0,137, 0, 0, 0,
+138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,
+138, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,
+139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,141, 0, 0, 0,144, 0, 0, 0,
+141, 0, 0, 0,146, 0, 0, 0,149, 0, 0, 0,146, 0, 0, 0,151, 0, 0, 0,
+151, 0, 0, 0,151, 0, 0, 0,152, 0, 0, 0,151, 0, 0, 0,154, 0, 0, 0,
+160, 0, 0, 0,154, 0, 0, 0,162, 0, 0, 0,162, 0, 0, 0,162, 0, 0, 0,
+164, 0, 0, 0,170, 0, 0, 0,164, 0, 0, 0,172, 0, 0, 0,176, 0, 0, 0,
+172, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,179, 0, 0, 0,
+179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,180, 0, 0, 0,
+180, 0, 0, 0,180, 0, 0, 0,181, 0, 0, 0,181, 0, 0, 0,181, 0, 0, 0,
+182, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,183, 0, 0, 0,183, 0, 0, 0,
+183, 0, 0, 0,184, 0, 0, 0,184, 0, 0, 0,184, 0, 0, 0,185, 0, 0, 0,
+185, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,186, 0, 0, 0,186, 0, 0, 0,
+187, 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,188, 0, 0, 0,188, 0, 0, 0,
+188, 0, 0, 0,189, 0, 0, 0,189, 0, 0, 0,189, 0, 0, 0,190, 0, 0, 0,
+190, 0, 0, 0,190, 0, 0, 0,191, 0, 0, 0,191, 0, 0, 0,191, 0, 0, 0,
+192, 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,193, 0, 0, 0,193, 0, 0, 0,
+193, 0, 0, 0,194, 0, 0, 0,194, 0, 0, 0,194, 0, 0, 0,195, 0, 0, 0,
+195, 0, 0, 0,195, 0, 0, 0,196, 0, 0, 0,196, 0, 0, 0,196, 0, 0, 0,
+197, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,198, 0, 0, 0,198, 0, 0, 0,
+198, 0, 0, 0,199, 0, 0, 0,199, 0, 0, 0,199, 0, 0, 0,200, 0, 0, 0,
+200, 0, 0, 0,200, 0, 0, 0,201, 0, 0, 0,201, 0, 0, 0,201, 0, 0, 0,
+202, 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,203, 0, 0, 0,203, 0, 0, 0,
+203, 0, 0, 0,204, 0, 0, 0,204, 0, 0, 0,204, 0, 0, 0,205, 0, 0, 0,
+205, 0, 0, 0,205, 0, 0, 0,206, 0, 0, 0,206, 0, 0, 0,206, 0, 0, 0,
+207, 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,208, 0, 0, 0,208, 0, 0, 0,
+208, 0, 0, 0,209, 0, 0, 0,209, 0, 0, 0,209, 0, 0, 0,210, 0, 0, 0,
+210, 0, 0, 0,210, 0, 0, 0,211, 0, 0, 0,211, 0, 0, 0,211, 0, 0, 0,
+212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,
+214, 0, 0, 0,227, 0, 0, 0,214, 0, 0, 0,235, 0, 0, 0,237, 0, 0, 0,
+237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,238, 0, 0, 0,
+238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,239, 0, 0, 0,
+239, 0, 0, 0,239, 0, 0, 0,240, 0, 0, 0,240, 0, 0, 0,240, 0, 0, 0,
+241, 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,
+242, 0, 0, 0,243, 0, 0, 0,243, 0, 0, 0,243, 0, 0, 0,244, 0, 0, 0,
+244, 0, 0, 0,244, 0, 0, 0,245, 0, 0, 0,245, 0, 0, 0,245, 0, 0, 0,
+246, 0, 0, 0,246, 0, 0, 0,246, 0, 0, 0,247, 0, 0, 0,247, 0, 0, 0,
+247, 0, 0, 0,248, 0, 0, 0,248, 0, 0, 0,248, 0, 0, 0,250, 0, 0, 0,
+254, 0, 0, 0,250, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
+ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0,
+ 2, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0,
+ 3, 1, 0, 0, 3, 1, 0, 0, 5, 1, 0, 0, 9, 1, 0, 0, 5, 1, 0, 0,
+ 11, 1, 0, 0, 15, 1, 0, 0, 11, 1, 0, 0, 17, 1, 0, 0, 17, 1, 0, 0,
+ 17, 1, 0, 0, 18, 1, 0, 0, 18, 1, 0, 0, 18, 1, 0, 0, 19, 1, 0, 0,
+ 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0,
+ 19, 1, 0, 0, 20, 1, 0, 0, 20, 1, 0, 0, 20, 1, 0, 0, 21, 1, 0, 0,
+ 21, 1, 0, 0, 21, 1, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0,
+ 24, 1, 0, 0, 29, 1, 0, 0, 24, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0,
+ 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0,
+ 31, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0,
+ 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 34, 1, 0, 0,
+ 42, 1, 0, 0, 34, 1, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 44, 1, 0, 0,
+ 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0,
+ 50, 1, 0, 0, 51, 1, 0, 0, 51, 1, 0, 0, 51, 1, 0, 0, 52, 1, 0, 0,
+ 52, 1, 0, 0, 52, 1, 0, 0, 53, 1, 0, 0, 53, 1, 0, 0, 53, 1, 0, 0,
+ 54, 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0, 55, 1, 0, 0, 55, 1, 0, 0,
+ 55, 1, 0, 0, 56, 1, 0, 0, 56, 1, 0, 0, 56, 1, 0, 0, 57, 1, 0, 0,
+ 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0,
+ 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0,
+ 58, 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0, 60, 1, 0, 0,
+ 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0,
+ 60, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0,
+ 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0,
+ 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0,
+ 63, 1, 0, 0, 63, 1, 0, 0, 63, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0,
+ 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0,
+ 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0,
+ 65, 1, 0, 0, 65, 1, 0, 0, 66, 1, 0, 0, 66, 1, 0, 0, 66, 1, 0, 0,
+ 67, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0, 68, 1, 0, 0, 68, 1, 0, 0,
+ 68, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0,
+ 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0,
+ 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0,
+ 71, 1, 0, 0, 71, 1, 0, 0, 71, 1, 0, 0, 72, 1, 0, 0, 72, 1, 0, 0,
+ 72, 1, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, 17, 0, 0, 0, 79,110,101, 83,
+111,117,114, 99,101, 79,110,101, 68,101,115,116, 0, 1, 0, 0, 0,143, 1, 0,
+ 0, 18, 0, 0, 0, 84,119,111, 83,111,117,114, 99,101,115, 79,110,101, 68,101,
+115,116, 0, 2, 0, 0, 0,143, 1, 0, 0, 20, 0, 0, 0, 84,104,114,101,101,
+ 83,111,117,114, 99,101,115, 79,110,101, 68,101,115,116, 0, 3, 0, 0, 0,143,
+ 1, 0, 0, 18, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101, 84,119,111, 68,
+101,115,116,115, 0, 4, 0, 0, 0,143, 1, 0, 0, 20, 0, 0, 0, 79,110,101,
+ 83,111,117,114, 99,101, 84,104,114,101,101, 68,101,115,116,115, 0, 5, 0, 0,
+ 0,143, 1, 0, 0, 13, 0, 0, 0,104,111,117,103,104, 95,104,101,105,103,104,
+116, 0, 6, 0, 0, 0,143, 1, 0, 0, 13, 0, 0, 0,105,110,116, 95,100, 97,
+116, 97,116,121,112,101, 0,182, 0, 0, 0,143, 1, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_process51/im_process.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_process_be32.loh b/im/src/lua5/loh/im_process_be32.loh
new file mode 100755
index 0000000..be77d66
--- /dev/null
+++ b/im/src/lua5/loh/im_process_be32.loh
@@ -0,0 +1,817 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_process51/im_process_be32.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_process51/im_process_be32.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 0, 4, 4, 4, 8, 0, 0, 0, 0, 21, 64,108,117, 97,
+ 53, 47,105,109, 95,112,114,111, 99,101,115,115, 46,108,117, 97, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 13, 0, 0, 1,144, 0, 0, 0, 36, 0, 0, 64,
+100, 0, 0,128,164, 0, 0,192,228, 0, 1, 1, 36, 0, 1, 65,100, 0, 0, 1,
+128, 0, 0, 1,193, 5, 0, 2, 3, 0, 0, 66,197, 5,192,130,198, 3, 0, 65,
+156, 0, 0, 1,128, 0, 0,193,193, 1, 0, 65,156, 0, 0, 1,128, 0, 1, 1,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 1, 65,193, 1, 0, 65,156, 0, 0, 1,
+128, 0, 1,129,193, 0, 1,194, 1, 2,128, 2, 64, 0, 0, 66,133, 5, 66, 2,
+134, 0, 0, 66,197, 5,194, 66,198, 3, 0, 65,156, 0, 0, 1,128, 0, 2,129,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 2,193,193, 5, 0, 2, 3, 0, 0, 66,
+197, 5,195, 2,198, 3, 0, 65,156, 0, 0, 1,128, 0, 3, 65,193, 4,128, 2,
+ 3, 0, 0, 66,133, 5, 67,130,134, 5,128, 2,195, 3, 0, 65,156, 0, 0, 65,
+133, 0, 1,129,228,135,129,193,137, 0, 0, 65,133, 0, 1,193,228,136, 1,193,
+137, 0, 0, 1,128, 0, 4, 65,193, 0, 2, 2, 36, 0, 2, 66,100, 2, 0, 65,
+156, 0, 0, 65,133, 0, 2,129,228,137, 1,193,137, 0,128, 1,128, 0, 4,193,
+193, 1, 0, 65,156, 0, 0, 65,133, 0, 2,193,228,138, 1,193,137, 0, 0, 65,
+133, 0, 3, 1,228,138,129,193,137, 0, 0, 1,128, 0, 5,129,193, 1, 0, 65,
+156, 0, 0, 1,128, 0, 5,193,193, 0, 3, 66, 36, 0, 3,130,100, 2, 0, 65,
+156, 0, 0, 1,128, 0, 6, 1,193, 1, 0, 65,156, 0, 0, 1,128, 0, 6, 65,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 6,129,193, 1, 0, 65,156, 0, 0, 1,
+128, 0, 6,193,193, 1, 0, 65,156, 0, 0, 1,128, 0, 7, 1,193, 1, 0, 65,
+156, 0, 0, 1,128, 0, 7, 65,193, 1, 0, 65,156, 0, 0, 1,128, 0, 7,129,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 7,193,193, 1, 0, 65,156, 0, 0, 1,
+128, 0, 8, 1,193, 1, 0, 65,156, 0, 0, 1,128, 0, 8, 65,193, 1, 0, 65,
+156, 0, 0, 1,128, 0, 8,129,193, 1, 0, 65,156, 0, 0, 1,128, 0, 8,193,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 9, 1,193, 1, 0, 65,156, 0, 0, 1,
+128, 0, 9, 65,193, 1, 0, 65,156, 0, 0, 1,128, 0, 9,129,193, 1, 0, 65,
+156, 0, 0, 1,128, 0, 9,193,193, 1, 0, 65,156, 0, 0, 1,128, 0, 10, 1,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 10, 65,193, 1, 0, 65,156, 0, 0, 1,
+128, 0, 10,129,193, 1, 0, 65,156, 0, 0, 1,128, 0, 10,193,193, 1, 0, 65,
+156, 0, 0, 1,128, 0, 11, 1,193, 1, 0, 65,156, 0, 0, 1,128, 0, 11, 65,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 11,129,193, 1, 0, 65,156, 0, 0, 1,
+128, 0, 11,193,193, 1, 0, 65,156, 0, 0, 1,128, 0, 12, 1,193, 1, 0, 65,
+156, 0, 0, 1,128, 0, 12, 65,193, 1, 0, 65,156, 0, 0, 1,128, 0, 12,129,
+193, 1, 0, 65,156, 0, 0, 1,128, 0, 12,193,193, 1, 0, 65,156, 0, 0, 1,
+128, 0, 13, 1,193, 1, 0, 65,156, 0, 0, 1,128, 0, 13, 65,193, 1, 0, 65,
+156, 0, 0, 1,128, 0, 13,129,193, 1, 0, 65,156, 0, 0, 1,128, 0, 13,193,
+193, 1, 0, 65,156, 1,128, 1,128, 0, 14, 1,193, 4, 0, 2, 3, 0, 3,194,
+100, 2, 0, 65,156, 0, 0, 65,133, 0, 4, 1,228,156,129,193,137, 0, 4, 65,
+164, 0, 0, 1,192, 0, 14,130, 1, 5,128, 2, 67, 3, 0, 3, 0, 3, 0, 65,
+220, 0, 0, 1,192, 0, 14,194, 1, 5,128, 2, 67, 3, 0, 3, 0, 3, 0, 65,
+220, 0, 0, 1,192, 0, 15, 2, 1, 1, 0, 65,220, 0, 0, 1,192, 0, 15, 66,
+ 1, 1, 0, 65,220, 0, 0, 1,192, 0, 15,130, 1, 1, 0, 65,220, 0, 0, 1,
+192, 0, 15,194, 1, 1, 0, 65,220, 0, 0, 1,192, 0, 16, 2, 1, 1, 0, 65,
+220, 0, 0, 1,192, 0, 16, 66, 1, 1, 0, 65,220, 0,128, 1,192, 0, 16,130,
+ 1, 1, 0, 65,220, 0, 0, 1,192, 0, 16,194, 1, 1, 0, 65,220, 0, 0, 1,
+192, 0, 17, 2, 1, 1, 0, 65,220, 0,128, 1,192, 0, 17, 66, 1, 1, 0, 65,
+220, 0, 0, 65,197, 0, 4,130, 36,163, 2, 1,201, 0,128, 1,192, 0, 17,194,
+ 1, 1, 0, 65,220, 1, 0, 1,192, 0, 18, 2, 1, 1, 0, 65,220, 1,128, 1,
+192, 0, 18, 66, 1, 1, 0, 65,220, 0,128, 1,192, 0, 18,130, 1, 5,128, 2,
+ 67, 0, 0, 67, 5, 6, 82,195, 6, 3, 0, 65,220, 0, 0, 65,197, 0, 4,194,
+ 36,166, 2, 1,201, 0, 0, 65,197, 0, 5, 2, 36,166,130, 1,201, 0,128, 1,
+192, 0, 19,130, 1, 1, 0, 65,220, 0, 0, 1,192, 0, 19,194, 1, 1, 0, 65,
+220, 0, 0, 1,192, 0, 20, 2, 1, 5, 0, 2, 67, 0, 0, 66,197, 5,212, 66,
+198, 6, 0, 3, 3, 3, 0, 65,220, 0, 0, 1,192, 0, 20,130, 1, 1, 0, 65,
+220, 0, 0, 1,192, 0, 20,194, 1, 1, 0, 65,220, 0, 0, 1,192, 0, 21, 2,
+ 1, 1, 0, 65,220, 0, 0, 65,197, 0, 5, 66, 36,170,130, 1,201, 2, 0, 1,
+192, 0, 21,130, 1, 5, 0, 2, 67, 0, 0, 66,197, 5,194, 2,198, 0, 0, 67,
+ 5, 6, 67, 3, 6, 3, 0, 65,220, 1, 0, 1,192, 0, 21,194, 1, 5, 0, 2,
+ 67, 0, 0, 66,197, 5,214, 2,198, 0, 0, 67, 5, 6, 86, 67, 6, 3, 0, 65,
+220, 0, 0, 65,197, 0, 5,130, 36,173, 2, 1,201, 0, 0, 65,197, 0, 5,194,
+ 36,173,130, 1,201, 0, 0, 1,192, 0, 23, 2, 1, 5,128, 2, 67, 0, 0, 67,
+ 5, 6, 67, 3, 6, 3, 0, 65,220, 0, 0, 1,192, 0, 23, 66, 1, 1, 0, 65,
+220, 0,128, 1,192, 0, 23,130, 1, 1, 0, 65,220, 0, 0, 1,192, 0, 23,194,
+ 1, 1, 0, 65,220, 0, 0, 1,192, 0, 24, 2, 1, 1, 0, 65,220, 0, 0, 1,
+192, 0, 24, 66, 1, 1, 0, 65,220, 0, 0, 1,192, 0, 24,130, 1, 1, 0, 65,
+220, 0, 0, 1,192, 0, 24,194, 1, 5,128, 2, 67, 0, 0, 67, 5, 6, 86, 67,
+ 6, 3, 0, 65,220, 0, 0, 1,192, 0, 25, 2, 1, 5,128, 2, 67, 0, 0, 67,
+ 5, 6, 86, 67, 6, 3, 0, 65,220, 0, 0, 1,192, 0, 25, 66, 1, 1, 0, 65,
+220, 0, 0, 1,192, 0, 25,130, 1, 5, 0, 2, 67, 0, 0, 66,197, 5,195,130,
+198, 6, 0, 3, 3, 3, 0, 65,220, 0, 0, 1,192, 0, 25,194, 1, 5, 0, 2,
+ 67, 0, 0, 66,197, 5,195,130,198, 6, 0, 3, 3, 3, 0, 65,220, 0, 0, 1,
+192, 0, 26, 2, 1, 5, 0, 2, 67, 0, 0, 66,197, 5,195,130,198, 6, 0, 3,
+ 3, 3, 0, 65,220, 0,128, 1,192, 0, 26, 66, 1, 1, 0, 65,220, 0, 0, 1,
+192, 0, 26,130, 1, 5, 0, 2, 67, 0, 0, 66,197, 5,195,130,198, 6, 0, 3,
+ 3, 3, 0, 65,220, 0, 0, 1,192, 0, 26,194, 1, 5, 0, 2, 67, 0, 0, 66,
+197, 5,195,130,198, 6, 0, 3, 3, 3, 0, 65,220, 0, 0, 1,192, 0, 27, 2,
+ 1, 1, 0, 65,220, 0, 0, 1,192, 0, 27, 66, 1, 1, 0, 65,220, 0, 0, 1,
+192, 0, 27,130, 1, 1, 0, 65,220, 0, 0, 1,192, 0, 27,194, 1, 5, 0, 2,
+ 67, 0, 0, 66,197, 5,195,130,198, 6, 0, 3, 3, 3, 0, 65,220, 0, 0, 1,
+192, 0, 28, 2, 1, 5, 0, 2, 67, 0, 0, 66,197, 5,195,130,198, 6, 0, 3,
+ 3, 3, 0, 65,220, 0, 0, 1,192, 0, 28, 66, 1, 1, 0, 65,220, 0, 0, 1,
+192, 0, 28,130, 1, 1, 0, 65,220, 0,128, 0, 30, 0, 0, 0,115, 4, 0, 0,
+ 0, 19, 65,110, 97,108,121,122,101, 70,105,110,100, 82,101,103,105,111,110,115,
+ 0, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 7, 85, 83, 72, 79, 82, 84,
+ 0, 4, 0, 0, 0, 21, 80,114,111, 99,101,115,115, 80,101,114,105,109,101,116,
+101,114, 76,105,110,101, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115, 82,
+101,109,111,118,101, 66,121, 65,114,101, 97, 0, 4, 0, 0, 0, 17, 80,114,111,
+ 99,101,115,115, 70,105,108,108, 72,111,108,101,115, 0, 4, 0, 0, 0, 18, 80,
+114,111, 99,101,115,115, 72,111,117,103,104, 76,105,110,101,115, 0, 3, 64,102,
+128, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 71, 82, 65, 89, 0, 4, 0, 0, 0,
+ 4, 73, 78, 84, 0, 4, 0, 0, 0, 22, 80,114,111, 99,101,115,115, 72,111,117,
+103,104, 76,105,110,101,115, 68,114, 97,119, 0, 4, 0, 0, 0, 25, 80,114,111,
+ 99,101,115,115, 68,105,115,116, 97,110, 99,101, 84,114, 97,110,115,102,111,114,
+109, 0, 4, 0, 0, 0, 6, 70, 76, 79, 65, 84, 0, 4, 0, 0, 0, 23, 80,114,
+111, 99,101,115,115, 82,101,103,105,111,110, 97,108, 77, 97,120,105,109,117,109,
+ 0, 4, 0, 0, 0, 7, 66, 73, 78, 65, 82, 89, 0, 4, 0, 0, 0, 17, 80,114,
+111, 99,101,115,115, 82,101,100,117, 99,101, 78,101,119, 0, 4, 0, 0, 0, 17,
+ 80,114,111, 99,101,115,115, 82,101,115,105,122,101, 78,101,119, 0, 4, 0, 0,
+ 0, 17, 80,114,111, 99,101,115,115, 82,101,100,117, 99,101, 66,121, 52, 0, 4,
+ 0, 0, 0, 15, 80,114,111, 99,101,115,115, 67,114,111,112, 78,101,119, 0, 4,
+ 0, 0, 0, 14, 80,114,111, 99,101,115,115, 73,110,115,101,114,116, 0, 4, 0,
+ 0, 0, 21, 80,114,111, 99,101,115,115, 65,100,100, 77, 97,114,103,105,110,115,
+ 78,101,119, 0, 4, 0, 0, 0, 17, 80,114,111, 99,101,115,115, 82,111,116, 97,
+116,101, 78,101,119, 0, 4, 0, 0, 0, 17, 80,114,111, 99,101,115,115, 82,111,
+116, 97,116,101, 82,101,102, 0, 4, 0, 0, 0, 16, 80,114,111, 99,101,115,115,
+ 82,111,116, 97,116,101, 57, 48, 0, 4, 0, 0, 0, 17, 80,114,111, 99,101,115,
+115, 82,111,116, 97,116,101, 49, 56, 48, 0, 4, 0, 0, 0, 14, 80,114,111, 99,
+101,115,115, 77,105,114,114,111,114, 0, 4, 0, 0, 0, 12, 80,114,111, 99,101,
+115,115, 70,108,105,112, 0, 4, 0, 0, 0, 14, 80,114,111, 99,101,115,115, 82,
+ 97,100,105, 97,108, 0, 4, 0, 0, 0, 25, 80,114,111, 99,101,115,115, 71,114,
+ 97,121, 77,111,114,112,104, 67,111,110,118,111,108,118,101, 0, 4, 0, 0, 0,
+ 22, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 69,114,111,
+100,101, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,
+111,114,112,104, 68,105,108, 97,116,101, 0, 4, 0, 0, 0, 21, 80,114,111, 99,
+101,115,115, 71,114, 97,121, 77,111,114,112,104, 79,112,101,110, 0, 4, 0, 0,
+ 0, 22, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 67,108,
+111,115,101, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 71,114, 97,121,
+ 77,111,114,112,104, 84,111,112, 72, 97,116, 0, 4, 0, 0, 0, 21, 80,114,111,
+ 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 87,101,108,108, 0, 4, 0,
+ 0, 0, 25, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 71,
+114, 97,100,105,101,110,116, 0, 4, 0, 0, 0, 24, 80,114,111, 99,101,115,115,
+ 66,105,110, 77,111,114,112,104, 67,111,110,118,111,108,118,101, 0, 4, 0, 0,
+ 0, 21, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 69,114,111,
+100,101, 0, 4, 0, 0, 0, 22, 80,114,111, 99,101,115,115, 66,105,110, 77,111,
+114,112,104, 68,105,108, 97,116,101, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,
+115,115, 66,105,110, 77,111,114,112,104, 79,112,101,110, 0, 4, 0, 0, 0, 21,
+ 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,108,111,115,101,
+ 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,
+104, 79,117,116,108,105,110,101, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,
+115, 66,105,110, 77,111,114,112,104, 84,104,105,110, 0, 4, 0, 0, 0, 22, 80,
+114,111, 99,101,115,115, 77,101,100,105, 97,110, 67,111,110,118,111,108,118,101,
+ 0, 4, 0, 0, 0, 21, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,111,
+110,118,111,108,118,101, 0, 4, 0, 0, 0, 27, 80,114,111, 99,101,115,115, 82,
+ 97,110,107, 67,108,111,115,101,115,116, 67,111,110,118,111,108,118,101, 0, 4,
+ 0, 0, 0, 23, 80,114,111, 99,101,115,115, 82, 97,110,107, 77, 97,120, 67,111,
+110,118,111,108,118,101, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 82,
+ 97,110,107, 77,105,110, 67,111,110,118,111,108,118,101, 0, 4, 0, 0, 0, 16,
+ 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101, 0, 4, 0, 0, 0,
+ 19, 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101, 83,101,112, 0,
+ 4, 0, 0, 0, 19, 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101,
+ 82,101,112, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115, 67,111,110,118,
+111,108,118,101, 68,117, 97,108, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,
+115, 67,111,109,112, 97,115,115, 67,111,110,118,111,108,118,101, 0, 4, 0, 0,
+ 0, 20, 80,114,111, 99,101,115,115, 77,101, 97,110, 67,111,110,118,111,108,118,
+101, 0, 4, 0, 0, 0, 24, 80,114,111, 99,101,115,115, 71, 97,117,115,115,105,
+ 97,110, 67,111,110,118,111,108,118,101, 0, 4, 0, 0, 0, 23, 80,114,111, 99,
+101,115,115, 66, 97,114,108,101,116,116, 67,111,110,118,111,108,118,101, 0, 4,
+ 0, 0, 0, 22, 80,114,111, 99,101,115,115, 73,110,116,101,114,108, 97, 99,101,
+ 83,112,108,105,116, 0, 4, 0, 0, 0, 25, 80,114,111, 99,101,115,115, 73,110,
+116,101,114,108, 97, 99,101, 83,112,108,105,116, 78,101,119, 0, 4, 0, 0, 0,
+ 30, 80,114,111, 99,101,115,115, 68,105,102,102, 79,102, 71, 97,117,115,115,105,
+ 97,110, 67,111,110,118,111,108,118,101, 0, 4, 0, 0, 0, 29, 80,114,111, 99,
+101,115,115, 76, 97,112, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,110,118,
+111,108,118,101, 0, 4, 0, 0, 0, 21, 80,114,111, 99,101,115,115, 83,111, 98,
+101,108, 67,111,110,118,111,108,118,101, 0, 4, 0, 0, 0, 26, 80,114,111, 99,
+101,115,115, 83,112,108,105,110,101, 69,100,103,101, 67,111,110,118,111,108,118,
+101, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 80,114,101,119,105,116,
+116, 67,111,110,118,111,108,118,101, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,
+115,115, 90,101,114,111, 67,114,111,115,115,105,110,103, 0, 4, 0, 0, 0, 13,
+ 80,114,111, 99,101,115,115, 67, 97,110,110,121, 0, 4, 0, 0, 0, 22, 80,114,
+111, 99,101,115,115, 85,110, 65,114,105,116,104,109,101,116,105, 99, 79,112, 0,
+ 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115, 65,114,105,116,104,109,101,116,
+105, 99, 79,112, 0, 4, 0, 0, 0, 15, 80,114,111, 99,101,115,115, 85,110,115,
+104, 97,114,112, 0, 4, 0, 0, 0, 13, 80,114,111, 99,101,115,115, 83,104, 97,
+114,112, 0, 4, 0, 0, 0, 19, 80,114,111, 99,101,115,115, 83,104, 97,114,112,
+ 75,101,114,110,101,108, 0, 4, 0, 0, 0, 28, 80,114,111, 99,101,115,115, 65,
+114,105,116,104,109,101,116,105, 99, 67,111,110,115,116, 79,112, 78,101,119, 0,
+ 4, 0, 0, 0, 18, 80,114,111, 99,101,115,115, 66,108,101,110,100, 67,111,110,
+115,116, 0, 4, 0, 0, 0, 13, 80,114,111, 99,101,115,115, 66,108,101,110,100,
+ 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,
+109,112,108,101,120, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115, 77,101,
+114,103,101, 67,111,109,112,108,101,120, 0, 4, 0, 0, 0, 7, 67, 70, 76, 79,
+ 65, 84, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 77,117,108,116,105,
+112,108,101, 77,101, 97,110, 78,101,119, 0, 4, 0, 0, 0, 25, 80,114,111, 99,
+101,115,115, 77,117,108,116,105,112,108,101, 83,116,100, 68,101,118, 78,101,119,
+ 0, 4, 0, 0, 0, 22, 80,114,111, 99,101,115,115, 65,117,116,111, 67,111,118,
+ 97,114,105, 97,110, 99,101, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115,
+ 77,117,108,116,105,112,108,121, 67,111,110,106, 0, 4, 0, 0, 0, 26, 80,114,
+111, 99,101,115,115, 81,117, 97,110,116,105,122,101, 82, 71, 66, 85,110,105,102,
+111,114,109, 0, 4, 0, 0, 0, 4, 77, 65, 80, 0, 4, 0, 0, 0, 27, 80,114,
+111, 99,101,115,115, 81,117, 97,110,116,105,122,101, 71,114, 97,121, 85,110,105,
+102,111,114,109, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 69,120,112,
+ 97,110,100, 72,105,115,116,111,103,114, 97,109, 0, 4, 0, 0, 0, 25, 80,114,
+111, 99,101,115,115, 69,113,117, 97,108,105,122,101, 72,105,115,116,111,103,114,
+ 97,109, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 83,112,108,105,116,
+ 89, 67,104,114,111,109, 97, 78,101,119, 0, 4, 0, 0, 0, 16, 80,114,111, 99,
+101,115,115, 83,112,108,105,116, 72, 83, 73, 0, 4, 0, 0, 0, 16, 80,114,111,
+ 99,101,115,115, 77,101,114,103,101, 72, 83, 73, 0, 4, 0, 0, 0, 4, 82, 71,
+ 66, 0, 4, 0, 0, 0, 5, 66, 89, 84, 69, 0, 4, 0, 0, 0, 26, 80,114,111,
+ 99,101,115,115, 83,112,108,105,116, 67,111,109,112,111,110,101,110,116,115, 78,
+101,119, 0, 4, 0, 0, 0, 26, 80,114,111, 99,101,115,115, 77,101,114,103,101,
+ 67,111,109,112,111,110,101,110,116,115, 78,101,119, 0, 4, 0, 0, 0, 27, 80,
+114,111, 99,101,115,115, 78,111,114,109, 97,108,105,122,101, 67,111,109,112,111,
+110,101,110,116,115, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115, 82,101,
+112,108, 97, 99,101, 67,111,108,111,114, 0, 4, 0, 0, 0, 17, 80,114,111, 99,
+101,115,115, 66,105,116,119,105,115,101, 79,112, 0, 4, 0, 0, 0, 18, 80,114,
+111, 99,101,115,115, 66,105,116,119,105,115,101, 78,111,116, 0, 4, 0, 0, 0,
+ 15, 80,114,111, 99,101,115,115, 66,105,116, 77, 97,115,107, 0, 4, 0, 0, 0,
+ 16, 80,114,111, 99,101,115,115, 66,105,116, 80,108, 97,110,101, 0, 4, 0, 0,
+ 0, 17, 80,114,111, 99,101,115,115, 84,111,110,101, 71, 97,109,117,116, 0, 4,
+ 0, 0, 0, 19, 80,114,111, 99,101,115,115, 85,110, 78,111,114,109, 97,108,105,
+122,101, 0, 4, 0, 0, 0, 18, 80,114,111, 99,101,115,115, 68,105,114,101, 99,
+116, 67,111,110,118, 0, 4, 0, 0, 0, 16, 80,114,111, 99,101,115,115, 78,101,
+103, 97,116,105,118,101, 0, 4, 0, 0, 0, 30, 80,114,111, 99,101,115,115, 82,
+ 97,110,103,101, 67,111,110,116,114, 97,115,116, 84,104,114,101,115,104,111,108,
+100, 0, 4, 0, 0, 0, 25, 80,114,111, 99,101,115,115, 76,111, 99, 97,108, 77,
+ 97,120, 84,104,114,101,115,104,111,108,100, 0, 4, 0, 0, 0, 17, 80,114,111,
+ 99,101,115,115, 84,104,114,101,115,104,111,108,100, 0, 4, 0, 0, 0, 23, 80,
+114,111, 99,101,115,115, 84,104,114,101,115,104,111,108,100, 66,121, 68,105,102,
+102, 0, 4, 0, 0, 0, 27, 80,114,111, 99,101,115,115, 72,121,115,116,101,114,
+101,115,105,115, 84,104,114,101,115,104,111,108,100, 0, 4, 0, 0, 0, 27, 80,
+114,111, 99,101,115,115, 85,110,105,102,111,114,109, 69,114,114, 84,104,114,101,
+115,104,111,108,100, 0, 4, 0, 0, 0, 28, 80,114,111, 99,101,115,115, 68,105,
+102,117,115,105,111,110, 69,114,114, 84,104,114,101,115,104,111,108,100, 0, 4,
+ 0, 0, 0, 24, 80,114,111, 99,101,115,115, 80,101,114, 99,101,110,116, 84,104,
+114,101,115,104,111,108,100, 0, 4, 0, 0, 0, 21, 80,114,111, 99,101,115,115,
+ 79,116,115,117, 84,104,114,101,115,104,111,108,100, 0, 4, 0, 0, 0, 23, 80,
+114,111, 99,101,115,115, 77,105,110, 77, 97,120, 84,104,114,101,115,104,111,108,
+100, 0, 4, 0, 0, 0, 22, 80,114,111, 99,101,115,115, 83,108,105, 99,101, 84,
+104,114,101,115,104,111,108,100, 0, 4, 0, 0, 0, 16, 80,114,111, 99,101,115,
+115, 80,105,120,101,108, 97,116,101, 0, 4, 0, 0, 0, 17, 80,114,111, 99,101,
+115,115, 80,111,115,116,101,114,105,122,101, 0, 0, 0, 0, 24, 0, 0, 0, 0,
+ 0, 0, 0, 8, 0, 0, 0, 25, 0, 5, 0, 9, 0, 0, 0, 17, 0, 0, 1, 69,
+ 2,128, 1, 70, 0, 0, 65,133, 2,128, 1,192, 1, 0, 65,156, 0, 0, 1,133,
+ 0, 0, 1,192, 0, 0,130, 1, 3,130, 1,213, 0, 0, 2, 36, 0,128, 0, 0,
+ 1, 0, 0, 0, 1,128, 0, 0, 2, 0, 0, 0, 2,128, 0, 0, 3,130, 1,137,
+ 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0,
+ 7, 97,115,115,101,114,116, 0, 4, 0, 0, 0, 4, 78,101,119, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 24, 5, 1, 7, 8, 0, 0, 0,
+ 23, 0, 0, 0,133, 1, 64, 64,134, 0, 0, 0,192, 0, 0, 1, 4, 0,128, 1,
+ 68, 1, 0, 1,132, 1,128, 1,196, 3, 0,128,156, 2, 0, 0,196, 0, 0, 1,
+ 0, 1, 0, 1, 64, 0, 0,129,133, 0,128, 1,192, 1, 0, 1,156, 0, 0,128,
+220, 0, 0, 0,218,128, 0,192, 22, 1,128, 1, 0, 1, 0, 1, 64, 1,128, 1,
+ 30,128, 0, 0, 22, 1, 0, 0,158, 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0,
+ 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 7,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0,
+ 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0,
+ 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0,
+ 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 20, 0,
+ 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 24, 0,
+ 0, 0, 4, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0,
+ 0, 0, 0, 0, 22, 0, 0, 0, 4, 97,114,103, 0, 0, 0, 0, 0, 0, 0, 0,
+ 22, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0, 8, 0,
+ 0, 0, 22, 0, 0, 0, 4,114,101,116, 0, 0, 0, 0, 15, 0, 0, 0, 22, 0,
+ 0, 0, 5, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0, 7,104,101,105,
+103,104,116, 0, 0, 0, 0, 12, 99,111,108,111,114, 95,115,112, 97, 99,101, 0,
+ 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 5,102,117,
+110, 99, 0, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 10, 0,
+ 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13, 0,
+ 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0,
+ 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 6, 0,
+ 0, 0, 9,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 12, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 5,102,117,110, 99, 0, 0, 0, 0, 2, 0, 0, 0, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 50, 0, 5, 0, 11,
+ 0, 0, 0, 22, 0, 0, 1, 69, 2,128, 1, 70, 0, 0, 65,133, 2,128, 1,192,
+ 0, 0,130, 5, 4, 64,194, 6, 0, 1, 2, 65, 0, 0, 2,128, 1,128, 2, 28,
+ 0, 0, 65,156, 0, 0, 1,133, 0, 0, 1,192, 0, 1, 66, 1, 3,130, 1,213,
+ 0, 0, 2, 36, 0,128, 0, 0, 1, 0, 0, 0, 1,128, 0, 0, 2, 0, 0, 0,
+ 2,128, 0, 0, 3,130, 1,137, 0,128, 0, 30, 0, 0, 0, 6, 4, 0, 0, 0,
+ 3,105,109, 0, 4, 0, 0, 0, 7, 97,115,115,101,114,116, 0, 4, 0, 0, 0,
+ 7,115,116,114,105,110,103, 0, 4, 0, 0, 0, 7,102,111,114,109, 97,116, 0,
+ 4, 0, 0, 0, 24,117,110,100,101,102,105,110,101,100, 32,102,117,110, 99,116,
+105,111,110, 32, 96, 37,115, 39, 0, 4, 0, 0, 0, 4, 78,101,119, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 49, 5, 2, 7, 10, 0, 0,
+ 0, 24, 0, 0, 0,197, 1,192, 64,198, 0, 0, 1, 0, 0, 0, 1, 68, 0,128,
+ 1,132, 1, 0, 1,196, 1,128, 2, 4, 3, 0,128,220, 2, 0, 1, 4, 0, 0,
+ 1, 64, 0,128, 1,128, 1,128, 1,192, 0, 0,130, 5, 1, 0, 2, 64, 1, 0,
+ 2, 28, 0, 0,129, 28, 0, 0, 1, 26,128, 0,192, 22, 2, 0, 1, 64, 1,128,
+ 1,128, 1,128, 1, 94,128, 0, 0, 22, 1, 0, 0,222, 0,128, 0, 30, 0, 0,
+ 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101,
+ 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 7,117,110,112,
+ 97, 99,107, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40,
+ 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40,
+ 0, 0, 0, 40, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43,
+ 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 44,
+ 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45,
+ 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0, 11,115,114, 99, 95,
+105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 11,115,
+114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0,
+ 0, 4, 97,114,103, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 10,100,115,
+116, 95,105,109, 97,103,101, 0, 0, 0, 0, 8, 0, 0, 0, 23, 0, 0, 0, 4,
+114,101,116, 0, 0, 0, 0, 16, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 6,
+119,105,100,116,104, 0, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0,
+ 12, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 10,100, 97,116,
+ 97, 95,116,121,112,101, 0, 0, 0, 0, 5,102,117,110, 99, 0, 0, 0, 0, 22,
+ 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35,
+ 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35,
+ 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 49,
+ 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49,
+ 0, 0, 0, 49, 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0, 9,102,117,110, 99,
+110, 97,109,101, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 6,119,105,100,
+116,104, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7,104,101,105,103,104,
+116, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 99,111,108,111,114, 95,
+115,112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 10,100, 97,
+116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 5,
+102,117,110, 99, 0, 0, 0, 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 56, 0, 0, 0, 73, 0, 5, 0, 9, 0, 0, 0, 17, 0, 0, 1,
+ 69, 2,128, 1, 70, 0, 0, 65,133, 2,128, 1,192, 1, 0, 65,156, 0, 0, 1,
+133, 0, 0, 1,192, 0, 0,130, 1, 3,130, 1,213, 0, 0, 2, 36, 0,128, 0,
+ 0, 1, 0, 0, 0, 1,128, 0, 0, 2, 0, 0, 0, 2,128, 0, 0, 3,130, 1,
+137, 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0,
+ 0, 7, 97,115,115,101,114,116, 0, 4, 0, 0, 0, 4, 78,101,119, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 72, 5, 3, 7, 12, 0, 0,
+ 0, 25, 0, 0, 1, 5, 2, 64, 65, 6, 0, 0, 1, 64, 0, 0, 1,132, 0,128,
+ 1,196, 1, 0, 2, 4, 1,128, 2, 68, 3, 0,129, 28, 2, 0, 1, 68, 0, 0,
+ 1,128, 0,128, 1,192, 1, 0, 2, 0, 2, 0, 2, 64, 0, 0,130,133, 1,128,
+ 2,192, 1, 0, 2,156, 0, 0,129, 92, 0, 0, 1, 90,128, 0,192, 22, 2,128,
+ 1,128, 2, 0, 1,192, 1,128, 1,158,128, 0, 0, 22, 1, 0, 1, 30, 0,128,
+ 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,
+109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0,
+ 7,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66,
+ 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66,
+ 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 68,
+ 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 70, 0, 0, 0, 72, 0, 0, 0, 6,
+ 0, 0, 0, 11,115,114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 0,
+ 0, 0, 24, 0, 0, 0, 11,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0,
+ 0, 0, 0, 0, 0, 24, 0, 0, 0, 11,115,114, 99, 95,105,109, 97,103,101, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 4, 97,114,103, 0, 0, 0, 0,
+ 0, 0, 0, 0, 24, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0,
+ 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 4,114,101,116, 0, 0, 0, 0, 17, 0,
+ 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0,
+ 7,104,101,105,103,104,116, 0, 0, 0, 0, 12, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0,
+ 0, 5,102,117,110, 99, 0, 0, 0, 0, 17, 0, 0, 0, 57, 0, 0, 0, 57, 0,
+ 0, 0, 58, 0, 0, 0, 58, 0, 0, 0, 58, 0, 0, 0, 61, 0, 0, 0, 61, 0,
+ 0, 0, 61, 0, 0, 0, 61, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0,
+ 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 73, 0,
+ 0, 0, 6, 0, 0, 0, 9,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 12, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5,102,117,110, 99, 0, 0, 0, 0, 2,
+ 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 97,
+ 0, 5, 0, 9, 0, 0, 0, 17, 0, 0, 1, 69, 2,128, 1, 70, 0, 0, 65,133,
+ 2,128, 1,192, 1, 0, 65,156, 0, 0, 1,133, 0, 0, 1,192, 0, 0,130, 1,
+ 3,130, 1,213, 0, 0, 2, 36, 0,128, 0, 0, 1, 0, 0, 0, 1,128, 0, 0,
+ 2, 0, 0, 0, 2,128, 0, 0, 3,130, 1,137, 0,128, 0, 30, 0, 0, 0, 3,
+ 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 7, 97,115,115,101,114,116, 0,
+ 4, 0, 0, 0, 4, 78,101,119, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 84, 0, 0, 0, 96, 5, 1, 7, 10, 0, 0, 0, 35, 0, 0, 0,133, 1, 64, 64,
+134, 0, 0, 0,192, 0, 0, 1, 4, 0,128, 1, 68, 1, 0, 1,132, 1,128, 1,
+196, 3, 0,128,156, 0, 0, 0,197, 1,192, 64,198, 0, 0, 1, 0, 0, 0, 1,
+ 68, 0,128, 1,132, 1, 0, 1,196, 1,128, 2, 4, 3, 0,128,220, 2, 0, 1,
+ 4, 0, 0, 1, 64, 1, 0, 1,128, 1,128, 1,192, 0, 0,130, 5, 0,128, 2,
+ 64, 1, 0, 2, 28, 0, 0,129, 28, 0, 0, 1, 26,128, 1, 0, 22, 2, 0, 1,
+ 64, 1, 0, 1,128, 1,128, 1,192, 2, 0, 1, 94,128, 0,128, 22, 1, 0, 1,
+ 64, 1,128, 1,128, 1,128, 1, 94, 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0,
+ 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 7,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0,
+ 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0,
+ 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0,
+ 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 90, 0, 0, 0, 90, 0,
+ 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0,
+ 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 91, 0, 0, 0, 92, 0, 0, 0, 92, 0,
+ 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 94, 0, 0, 0, 94, 0,
+ 0, 0, 94, 0, 0, 0, 96, 0, 0, 0, 5, 0, 0, 0, 10,115,114, 99, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 4, 97,114,103,
+ 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 11,100,115,116, 95,105,109, 97,
+103,101, 49, 0, 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 11,100,115,116, 95,
+105,109, 97,103,101, 50, 0, 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 4,114,
+101,116, 0, 0, 0, 0, 24, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 6,119,
+105,100,116,104, 0, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 12,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 10,100, 97,116, 97,
+ 95,116,121,112,101, 0, 0, 0, 0, 5,102,117,110, 99, 0, 0, 0, 0, 17, 0,
+ 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 81, 0, 0, 0, 81, 0, 0, 0, 81, 0,
+ 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 96, 0,
+ 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0,
+ 0, 0, 96, 0, 0, 0, 97, 0, 0, 0, 6, 0, 0, 0, 9,102,117,110, 99,110,
+ 97,109,101, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6,119,105,100,116,
+104, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 99,111,108,111,114, 95,115,
+112, 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10,100, 97,116,
+ 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5,102,
+117,110, 99, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,103, 0, 0, 0,122, 0, 5, 0, 9, 0, 0, 0, 17, 0, 0, 1, 69,
+ 2,128, 1, 70, 0, 0, 65,133, 2,128, 1,192, 1, 0, 65,156, 0, 0, 1,133,
+ 0, 0, 1,192, 0, 0,130, 1, 3,130, 1,213, 0, 0, 2, 36, 0,128, 0, 0,
+ 1, 0, 0, 0, 1,128, 0, 0, 2, 0, 0, 0, 2,128, 0, 0, 3,130, 1,137,
+ 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0,
+ 7, 97,115,115,101,114,116, 0, 4, 0, 0, 0, 4, 78,101,119, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,108, 0, 0, 0,121, 5, 1, 7, 12, 0, 0, 0,
+ 46, 0, 0, 0,133, 1, 64, 64,134, 0, 0, 0,192, 0, 0, 1, 4, 0,128, 1,
+ 68, 1, 0, 1,132, 1,128, 1,196, 3, 0,128,156, 0, 0, 0,197, 1,192, 64,
+198, 0, 0, 1, 0, 0, 0, 1, 68, 0,128, 1,132, 1, 0, 1,196, 1,128, 2,
+ 4, 3, 0,128,220, 0, 0, 1, 5, 2, 64, 65, 6, 0, 0, 1, 64, 0, 0, 1,
+132, 0,128, 1,196, 1, 0, 2, 4, 1,128, 2, 68, 3, 0,129, 28, 2, 0, 1,
+ 68, 0, 0, 1,128, 1, 0, 1,192, 1,128, 2, 0, 2, 0, 2, 64, 0, 0,130,
+133, 0,128, 2,192, 1, 0, 2,156, 0, 0,129, 92, 0, 0, 1, 90,128, 1, 64,
+ 22, 2,128, 1,128, 1, 0, 1,192, 1,128, 2, 0, 2, 0, 2, 64, 2,128, 1,
+158,128, 0,192, 22, 1, 0, 1,128, 1,128, 1,192, 2, 0, 2, 0, 2, 0, 1,
+158, 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0,
+ 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4,
+ 0, 0, 0, 7,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0,
+ 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0,
+ 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,111, 0, 0, 0,111, 0,
+ 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0,
+ 0, 0,111, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0,
+ 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,115, 0,
+ 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0,
+ 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,116, 0,
+ 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0,
+ 0, 0,117, 0, 0, 0,119, 0, 0, 0,119, 0, 0, 0,119, 0, 0, 0,119, 0,
+ 0, 0,121, 0, 0, 0, 6, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 4, 97,114,103, 0, 0, 0, 0,
+ 0, 0, 0, 0, 45, 0, 0, 0, 11,100,115,116, 95,105,109, 97,103,101, 49, 0,
+ 0, 0, 0, 8, 0, 0, 0, 45, 0, 0, 0, 11,100,115,116, 95,105,109, 97,103,
+101, 50, 0, 0, 0, 0, 16, 0, 0, 0, 45, 0, 0, 0, 11,100,115,116, 95,105,
+109, 97,103,101, 51, 0, 0, 0, 0, 24, 0, 0, 0, 45, 0, 0, 0, 4,114,101,
+116, 0, 0, 0, 0, 33, 0, 0, 0, 45, 0, 0, 0, 5, 0, 0, 0, 6,119,105,
+100,116,104, 0, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 12, 99,
+111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 10,100, 97,116, 97, 95,
+116,121,112,101, 0, 0, 0, 0, 5,102,117,110, 99, 0, 0, 0, 0, 17, 0, 0,
+ 0,104, 0, 0, 0,104, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0,
+ 0,108, 0, 0, 0,108, 0, 0, 0,108, 0, 0, 0,108, 0, 0, 0,121, 0, 0,
+ 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0,
+ 0,121, 0, 0, 0,122, 0, 0, 0, 6, 0, 0, 0, 9,102,117,110, 99,110, 97,
+109,101, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6,119,105,100,116,104,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7,104,101,105,103,104,116, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10,100, 97,116, 97,
+ 95,116,121,112,101, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5,102,117,
+110, 99, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,126, 0, 0, 0,130, 0, 1, 0, 7, 0, 0, 0, 18, 0, 0, 0,100, 0,
+ 0, 0,133, 1, 64, 64,134, 0,128, 0,192, 0, 64,129, 11, 1, 0, 1, 28, 0,
+ 0,128,220, 0,128, 1, 0, 0, 64,193, 75, 1, 0, 1, 92, 0, 0,129, 28, 1,
+129, 0,204, 1, 0,128,156, 1, 65, 0,143,130, 0,128,206, 1,193, 64,204, 1,
+ 0, 0,222, 0,128, 0, 30, 0, 0, 0, 6, 4, 0, 0, 0, 5,109, 97,116,104,
+ 0, 4, 0, 0, 0, 5,115,113,114,116, 0, 4, 0, 0, 0, 6, 87,105,100,116,
+104, 0, 4, 0, 0, 0, 7, 72,101,105,103,104,116, 0, 3, 64, 0, 0, 0, 0,
+ 0, 0, 0, 3, 63,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0, 0, 0,127, 0, 0, 0,127, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 78,
+ 1, 0, 0, 94, 0,128, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0, 1, 0, 0, 0, 2,
+120, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0,
+ 0,127, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,
+ 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,
+ 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,129, 0, 0,
+ 0,129, 0, 0, 0,129, 0, 0, 0,130, 0, 0, 0, 3, 0, 0, 0, 6,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 4,115,113,114, 0,
+ 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 0, 5,114,109, 97,120, 0, 0, 0, 0,
+ 14, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,141, 0, 0, 0,
+144, 0, 3, 0, 7, 0, 0, 0, 14, 0, 0, 0,197, 1,192, 64,198, 0, 0, 1,
+ 0, 0,128, 1, 64, 1, 0, 1,128, 2, 0,128,220, 0, 0, 1, 5, 2, 64,129,
+ 6, 0, 0, 1, 64, 1,128, 1,128, 1,128,129, 28, 1,128, 1, 64, 1,128, 1,
+ 30, 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0,
+ 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4,
+ 0, 0, 0, 14, 80,114,111, 99,101,115,115, 82,101,100,117, 99,101, 0, 0, 0,
+ 0, 0, 0, 0, 0, 14, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0,
+ 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,143, 0, 0, 0,143, 0, 0,
+ 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0,
+ 0,144, 0, 0, 0, 4, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0,
+ 0, 0, 0, 0, 13, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0,
+ 0, 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,146, 0,
+ 0, 0,149, 0, 3, 0, 7, 0, 0, 0, 14, 0, 0, 0,197, 1,192, 64,198, 0,
+ 0, 1, 0, 0,128, 1, 64, 1, 0, 1,128, 2, 0,128,220, 0, 0, 1, 5, 2,
+ 64,129, 6, 0, 0, 1, 64, 1,128, 1,128, 1,128,129, 28, 1,128, 1, 64, 1,
+128, 1, 30, 0,128, 0, 30, 0, 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4,
+ 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 0, 0, 0, 14, 80,114,111, 99,101,115,115, 82,101,115,105,122,101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,147,
+ 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,148, 0, 0, 0,148,
+ 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148,
+ 0, 0, 0,149, 0, 0, 0, 4, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,
+101, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6,119,105,100,116,104, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0,
+ 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+151, 0, 0, 0,151, 0, 1, 0, 3, 0, 0, 0, 5, 0, 64, 0, 75, 1, 0,128,
+ 92, 0,192, 64, 79, 1, 0, 0, 94, 0,128, 0, 30, 0, 0, 0, 2, 4, 0, 0,
+ 0, 6, 87,105,100,116,104, 0, 3, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,
+151, 0, 0, 0,151, 0, 0, 0, 1, 0, 0, 0, 6,105,109, 97,103,101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 0,
+ 0, 0,152, 0, 1, 0, 3, 0, 0, 0, 5, 0, 64, 0, 75, 1, 0,128, 92, 0,
+192, 64, 79, 1, 0, 0, 94, 0,128, 0, 30, 0, 0, 0, 2, 4, 0, 0, 0, 7,
+ 72,101,105,103,104,116, 0, 3, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152,
+ 0, 0, 0,152, 0, 0, 0, 1, 0, 0, 0, 6,105,109, 97,103,101, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,154, 0, 0,
+ 0,160, 0, 5, 0, 13, 0, 0, 0, 19, 1, 0, 65, 77, 2,192, 1, 76, 2, 0,
+193,141, 3, 64, 1,140, 0, 0, 65,197, 3,192,129,198, 0, 0, 2, 0, 2,128,
+ 2, 64, 3, 0, 2,128, 2, 0,129,220, 0, 0, 66, 5, 4, 64,194, 6, 0, 0,
+ 2, 64, 3,128, 2,128, 0,128, 2,192, 1,128, 3, 0, 2,128, 66, 28, 1, 0,
+ 1,222, 0,128, 0, 30, 0, 0, 0, 4, 3, 63,240, 0, 0, 0, 0, 0, 0, 4,
+ 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 12, 80,114,111, 99,101,115,
+115, 67,114,111,112, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0,155, 0, 0,
+ 0,155, 0, 0, 0,156, 0, 0, 0,156, 0, 0, 0,157, 0, 0, 0,157, 0, 0,
+ 0,157, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,158, 0, 0,
+ 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0,
+ 0,158, 0, 0, 0,159, 0, 0, 0,160, 0, 0, 0, 8, 0, 0, 0, 10,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,
+120,109,105,110, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,120,109, 97,
+120, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,121,109,105,110, 0, 0,
+ 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,121,109, 97,120, 0, 0, 0, 0, 0,
+ 0, 0, 0, 18, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0, 2, 0, 0,
+ 0, 18, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 4, 0, 0, 0,
+ 18, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0, 10, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0,170, 0,
+ 5, 0, 13, 0, 0, 0, 19, 1, 0, 65, 77, 2,192, 1, 76, 2, 0,193,141, 3,
+ 64, 1,140, 0, 0, 65,197, 3,192,129,198, 0, 0, 2, 0, 2,128, 2, 64, 3,
+ 0, 2,128, 2, 0,129,220, 0, 0, 66, 5, 4, 64,194, 6, 0, 0, 2, 64, 3,
+128, 2,128, 0,128, 2,192, 1,128, 3, 0, 2,128, 66, 28, 1, 0, 1,222, 0,
+128, 0, 30, 0, 0, 0, 4, 3, 63,240, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
+ 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,101,
+ 66, 97,115,101,100, 0, 4, 0, 0, 0, 18, 80,114,111, 99,101,115,115, 65,100,
+100, 77, 97,114,103,105,110,115, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0,
+165, 0, 0, 0,165, 0, 0, 0,166, 0, 0, 0,166, 0, 0, 0,167, 0, 0, 0,
+167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,
+168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,
+168, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 0, 0, 8, 0, 0, 0,
+ 10,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0,
+ 0, 0, 5,120,109,105,110, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,
+120,109, 97,120, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,121,109,105,
+110, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5,121,109, 97,120, 0, 0,
+ 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0,
+ 2, 0, 0, 0, 18, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 4,
+ 0, 0, 0, 18, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0,
+ 0, 10, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0,
+ 0,176, 0, 4, 0, 13, 0, 0, 0, 26, 0, 0, 1, 5, 2, 64, 65, 6, 0, 64,
+129, 75, 1, 0,129, 92, 0, 64,193,139, 1, 0,129,156, 0,128, 1,192, 1, 0,
+ 2, 0, 2,128,193, 28, 0, 0, 1,133, 3, 65, 1,134, 0, 0, 1,192, 2, 0,
+ 2, 0, 2,128, 2, 64, 2, 0,129,156, 0, 0, 1,197, 3,193, 65,198, 0, 0,
+ 2, 0, 3, 0, 2, 64, 0,128, 2,128, 1, 0, 2,192, 1,128, 3, 0, 3, 0,
+129,220, 3, 0, 2, 0, 1,128, 1,222, 0,128, 0, 30, 0, 0, 0, 6, 4, 0,
+ 0, 0, 3,105,109, 0, 4, 0, 0, 0, 22, 80,114,111, 99,101,115,115, 67, 97,
+108, 99, 82,111,116, 97,116,101, 83,105,122,101, 0, 4, 0, 0, 0, 6, 87,105,
+100,116,104, 0, 4, 0, 0, 0, 7, 72,101,105,103,104,116, 0, 4, 0, 0, 0,
+ 17, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0,
+ 0, 0, 14, 80,114,111, 99,101,115,115, 82,111,116, 97,116,101, 0, 0, 0, 0,
+ 0, 0, 0, 0, 26, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,
+173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,
+173, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,
+174, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,
+175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,
+175, 0, 0, 0,175, 0, 0, 0,176, 0, 0, 0, 7, 0, 0, 0, 10,115,114, 99,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 5, 99,
+111,115, 48, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 5,115,105,110, 48,
+ 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 6,111,114,100,101,114, 0, 0,
+ 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 6,119,105,100,116,104, 0, 0, 0, 0,
+ 9, 0, 0, 0, 25, 0, 0, 0, 7,104,101,105,103,104,116, 0, 0, 0, 0, 9,
+ 0, 0, 0, 25, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0,
+ 0, 15, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0,
+ 0,179, 0, 1, 0, 3, 0, 0, 0, 4, 0, 64, 0, 75, 1, 0, 0, 93, 0, 0,
+ 0, 94, 0,128, 0, 30, 0, 0, 0, 1, 4, 0, 0, 0, 7, 72,101,105,103,104,
+116, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0, 0,
+ 0,179, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6,105,109, 97,103,101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179,
+ 0, 0, 0,179, 0, 1, 0, 3, 0, 0, 0, 4, 0, 64, 0, 75, 1, 0, 0, 93,
+ 0, 0, 0, 94, 0,128, 0, 30, 0, 0, 0, 1, 4, 0, 0, 0, 6, 87,105,100,
+116,104, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0,179, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+212, 0, 0, 0,212, 0, 1, 0, 3, 0, 0, 0, 13, 0, 64, 0, 75, 1, 0,128,
+ 92, 0, 0, 0, 90,128, 0,192, 22, 0, 64, 0, 75, 1, 0, 0, 93, 0, 0, 0,
+ 94,128, 0,192, 22, 0, 64, 0, 75, 1, 0,128, 92, 0,192, 64, 79, 1, 0, 0,
+ 94, 0,128, 0, 30, 0, 0, 0, 2, 4, 0, 0, 0, 7, 72,101,105,103,104,116,
+ 0, 3, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0,
+ 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0,
+ 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 0, 6,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,214, 0, 0, 0,227, 0, 1, 0, 8, 0, 0, 0, 36, 0, 64, 0, 75,
+ 1, 0,128, 92, 0,192, 64, 79, 0, 0,128,133, 1, 64,192,134, 0, 64, 0,203,
+ 1, 0,128,220, 0, 0, 65, 1, 1,128,128,156, 0, 0, 0,154,128, 0, 0, 22,
+ 0,193, 0, 76, 0, 1, 64,133, 1, 65,128,134, 0, 0, 0,192, 2, 0, 1, 3,
+ 0,128, 1, 64, 2, 0,128,156, 0, 1, 64,197, 1,193,128,198, 0, 0, 1, 0,
+ 2,128, 1, 67, 0, 64, 1,139, 1, 0,129,156, 3, 64, 65,143, 2, 0,128,220,
+ 0, 1, 65, 5, 2, 65,193, 6, 0, 0, 1, 64, 1, 0, 1,128, 1,128, 1,192,
+ 2, 0, 65, 28, 1, 0, 1, 0, 1,128, 1, 64, 1,128, 1, 30, 0,128, 0, 30,
+ 0, 0, 0, 8, 4, 0, 0, 0, 7, 72,101,105,103,104,116, 0, 3, 64, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 5,109, 97,116,104, 0, 4, 0, 0, 0, 4,
+109,111,100, 0, 3, 63,240, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3,105,109,
+ 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,
+101,100, 0, 4, 0, 0, 0, 22, 80,114,111, 99,101,115,115, 73,110,116,101,114,
+108, 97, 99,101, 83,112,108,105,116, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0,
+ 0,216, 0, 0, 0,216, 0, 0, 0,216, 0, 0, 0,217, 0, 0, 0,217, 0, 0,
+ 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0,
+ 0,217, 0, 0, 0,218, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0, 0,
+ 0,221, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,222, 0, 0, 0,222, 0, 0,
+ 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0,
+ 0,222, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0,
+ 0,225, 0, 0, 0,225, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,226, 0, 0,
+ 0,227, 0, 0, 0, 4, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 12,100,115,116, 95,104,101,105,103,
+104,116, 49, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 11,100,115,116, 95,
+105,109, 97,103,101, 49, 0, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 0, 11,100,
+115,116, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 26, 0, 0, 0, 35, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,229, 0, 0, 0,235, 0, 1, 0, 3, 0, 0,
+ 0, 14, 0, 64, 0, 75, 1, 0,128, 92, 0, 0, 64,133, 1, 64,128,134, 0,128,
+128, 87,128, 0,192, 22, 0, 0, 64,133, 1, 64,192,134, 0,128,128, 23,128, 0,
+ 64, 22, 0, 0, 64,133, 1, 65, 0, 70, 1, 0, 0, 94, 0,128, 0, 30, 0, 0,
+ 0, 5, 4, 0, 0, 0, 9, 68, 97,116, 97, 84,121,112,101, 0, 4, 0, 0, 0,
+ 3,105,109, 0, 4, 0, 0, 0, 5, 66, 89, 84, 69, 0, 4, 0, 0, 0, 7, 85,
+ 83, 72, 79, 82, 84, 0, 4, 0, 0, 0, 4, 73, 78, 84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 14, 0, 0, 0,230, 0, 0, 0,230, 0, 0, 0,231, 0, 0, 0,231, 0,
+ 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0,
+ 0, 0,231, 0, 0, 0,232, 0, 0, 0,232, 0, 0, 0,234, 0, 0, 0,235, 0,
+ 0, 0, 2, 0, 0, 0, 6,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 10,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 2, 0,
+ 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0, 0, 0,254, 0,
+ 3, 0, 9, 0, 0, 0, 13, 0, 0, 0,197, 1,192, 64,198, 0, 0, 1, 0, 1,
+ 0,128,220, 0, 0, 1, 5, 2, 64,129, 6, 0, 0, 1, 64, 0,128, 1,128, 1,
+128, 1,192, 1, 0, 2, 0, 2,128, 65, 28, 1, 0, 0,222, 0,128, 0, 30, 0,
+ 0, 0, 3, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 25, 80,114,
+111, 99,101,115,115, 65,114,105,116,104,109,101,116,105, 99, 67,111,110,115,116,
+ 79,112, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0,251, 0, 0, 0,251, 0,
+ 0, 0,251, 0, 0, 0,251, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0,
+ 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,253, 0,
+ 0, 0,254, 0, 0, 0, 4, 0, 0, 0, 10,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 10,115,114, 99, 95, 99,111,110,
+115,116, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 3,111,112, 0, 0, 0,
+ 0, 0, 0, 0, 0, 12, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0,
+ 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5,
+ 0, 0, 1, 9, 0, 2, 0, 6, 0, 0, 0, 11, 0, 0, 0,133, 1, 64, 64,134,
+ 0, 64,128,198, 1, 0,128,156, 0, 0, 0,197, 1,192,192,198, 0, 0, 1, 0,
+ 1, 0, 1, 64, 1,128, 64,220, 1, 0, 0,158, 0,128, 0, 30, 0, 0, 0, 4,
+ 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109, 97,103,101, 67,114,
+101, 97,116,101, 66, 97,115,101,100, 0, 3, 63,240, 0, 0, 0, 0, 0, 0, 4,
+ 0, 0, 0, 20, 80,114,111, 99,101,115,115, 77,117,108,116,105,112,108,101, 77,
+101, 97,110, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 1, 6, 0, 0, 1, 6,
+ 0, 0, 1, 6, 0, 0, 1, 6, 0, 0, 1, 7, 0, 0, 1, 7, 0, 0, 1, 7,
+ 0, 0, 1, 7, 0, 0, 1, 7, 0, 0, 1, 8, 0, 0, 1, 9, 0, 0, 0, 3,
+ 0, 0, 0, 15,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0,
+ 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10,100,115,116, 95,105,109, 97,
+103,101, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 11, 0, 0, 1, 15, 0, 2, 0, 7, 0, 0, 0, 12, 0, 0, 0,133, 1,
+ 64, 64,134, 0, 64,128,198, 1, 0,128,156, 0, 0, 0,197, 1,192,192,198, 0,
+ 0, 1, 0, 0,128, 1, 64, 1, 0, 1,128, 2, 0, 64,220, 1, 0, 0,158, 0,
+128, 0, 30, 0, 0, 0, 4, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 3, 63,240,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 22, 80,114,111, 99,101,115,115, 77,117,
+108,116,105,112,108,101, 83,116,100, 68,101,118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12, 0, 0, 1, 12, 0, 0, 1, 12, 0, 0, 1, 12, 0, 0, 1, 12, 0, 0, 1,
+ 13, 0, 0, 1, 13, 0, 0, 1, 13, 0, 0, 1, 13, 0, 0, 1, 13, 0, 0, 1,
+ 13, 0, 0, 1, 14, 0, 0, 1, 15, 0, 0, 0, 3, 0, 0, 0, 15,115,114, 99,
+ 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0, 0, 0, 0, 0, 0, 0, 11,
+ 0, 0, 0, 11,109,101, 97,110, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0,
+ 0, 0, 11, 0, 0, 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0,
+ 4, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 24, 0, 0, 1,
+ 29, 0, 1, 0, 8, 0, 0, 0, 28, 0, 0, 0, 69, 0,192, 64, 70, 0, 0, 0,
+128, 2, 0, 0,195, 0, 0, 1, 69, 2,192,129, 70, 0, 0, 1,133, 3, 64,193,
+134, 3, 0,128, 92, 0, 0, 0,133, 1, 64, 64,134, 0, 0, 0,192, 2,128, 1,
+ 3, 0, 0, 1,133, 3, 65, 1,134, 0, 0, 1,197, 3,192,193,198, 3, 0,128,
+156, 0, 0, 0,197, 1,193, 64,198, 0, 0, 1, 0, 0,128, 1, 64, 1, 0, 1,
+128, 2, 0, 64,220, 0,128, 0,192, 1, 0, 1, 0, 1,128, 0,222, 0,128, 0,
+ 30, 0, 0, 0, 6, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17, 73,109,
+ 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0, 0, 5,
+ 71, 82, 65, 89, 0, 4, 0, 0, 0, 5, 66, 89, 84, 69, 0, 4, 0, 0, 0, 4,
+ 82, 71, 66, 0, 4, 0, 0, 0, 20, 80,114,111, 99,101,115,115, 83,112,108,105,
+116, 89, 67,104,114,111,109, 97, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 1,
+ 25, 0, 0, 1, 25, 0, 0, 1, 25, 0, 0, 1, 25, 0, 0, 1, 25, 0, 0, 1,
+ 25, 0, 0, 1, 25, 0, 0, 1, 25, 0, 0, 1, 25, 0, 0, 1, 26, 0, 0, 1,
+ 26, 0, 0, 1, 26, 0, 0, 1, 26, 0, 0, 1, 26, 0, 0, 1, 26, 0, 0, 1,
+ 26, 0, 0, 1, 26, 0, 0, 1, 26, 0, 0, 1, 27, 0, 0, 1, 27, 0, 0, 1,
+ 27, 0, 0, 1, 27, 0, 0, 1, 27, 0, 0, 1, 27, 0, 0, 1, 28, 0, 0, 1,
+ 28, 0, 0, 1, 28, 0, 0, 1, 29, 0, 0, 0, 3, 0, 0, 0, 10,115,114, 99,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 8,121,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 9, 0, 0, 0, 27, 0, 0, 0, 13, 99,
+104,114,111,109, 97, 95,105,109, 97,103,101, 0, 0, 0, 0, 18, 0, 0, 0, 27,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 34, 0, 0, 1, 42, 0, 1, 0, 14,
+ 0, 0, 0, 29, 0, 64, 0, 75, 1, 0,128, 92, 0, 0, 0,138, 0, 0, 64,193,
+ 0,128, 1, 0, 0, 0, 65, 65,128, 2,128,224, 0, 0,129,197, 3,192,193,198,
+ 1, 0, 2, 0, 0, 1, 2, 69, 4,193, 66, 70, 0, 0, 2,128, 6, 0, 2,195,
+ 0, 1, 3, 69, 6,193,131, 70, 2,128, 2, 92, 0, 0, 65,220,127,252,192,223,
+ 0, 1, 0,197, 1,193,192,198, 0, 0, 1, 0, 1, 0, 1, 64, 1,128, 64,220,
+ 0, 2, 0,197, 1, 0, 1, 0, 1, 0, 0,221, 0, 0, 0,222, 0,128, 0, 30,
+ 0, 0, 0, 9, 4, 0, 0, 0, 6, 68,101,112,116,104, 0, 3, 63,240, 0, 0,
+ 0, 0, 0, 0, 4, 0, 0, 0, 6,116, 97, 98,108,101, 0, 4, 0, 0, 0, 7,
+105,110,115,101,114,116, 0, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 0, 0,
+ 0, 5, 71, 82, 65, 89, 0, 4, 0, 0, 0, 23, 80,114,111, 99,101,115,115, 83,
+112,108,105,116, 67,111,109,112,111,110,101,110,116,115, 0, 4, 0, 0, 0, 7,
+117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 1, 35, 0,
+ 0, 1, 35, 0, 0, 1, 36, 0, 0, 1, 37, 0, 0, 1, 37, 0, 0, 1, 37, 0,
+ 0, 1, 37, 0, 0, 1, 38, 0, 0, 1, 38, 0, 0, 1, 38, 0, 0, 1, 38, 0,
+ 0, 1, 38, 0, 0, 1, 38, 0, 0, 1, 38, 0, 0, 1, 38, 0, 0, 1, 38, 0,
+ 0, 1, 38, 0, 0, 1, 38, 0, 0, 1, 37, 0, 0, 1, 40, 0, 0, 1, 40, 0,
+ 0, 1, 40, 0, 0, 1, 40, 0, 0, 1, 40, 0, 0, 1, 41, 0, 0, 1, 41, 0,
+ 0, 1, 41, 0, 0, 1, 41, 0, 0, 1, 42, 0, 0, 0, 7, 0, 0, 0, 10,115,
+114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 6,100,101,112,116,104, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 11,100,
+115,116, 95,105,109, 97,103,101,115, 0, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0,
+ 0, 12, 40,102,111,114, 32,105,110,100,101,120, 41, 0, 0, 0, 0, 6, 0, 0,
+ 0, 19, 0, 0, 0, 12, 40,102,111,114, 32,108,105,109,105,116, 41, 0, 0, 0,
+ 0, 6, 0, 0, 0, 19, 0, 0, 0, 11, 40,102,111,114, 32,115,116,101,112, 41,
+ 0, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 2,105, 0, 0, 0, 0, 7, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 44, 0, 0, 1, 48, 0,
+ 1, 0, 6, 0, 0, 0, 14, 0, 0, 0, 69, 0,192, 64, 70, 0, 64,128,134, 2,
+ 0, 0,195, 0, 0, 1, 69, 2,192,193, 70, 2,128,128, 92, 0, 0, 0,133, 1,
+ 65, 0,134, 0, 0, 0,192, 0,128, 1, 0, 1,128, 64,156, 1, 0, 0, 94, 0,
+128, 0, 30, 0, 0, 0, 5, 4, 0, 0, 0, 3,105,109, 0, 4, 0, 0, 0, 17,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 3, 63,240,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 82, 71, 66, 0, 4, 0, 0, 0, 23,
+ 80,114,111, 99,101,115,115, 77,101,114,103,101, 67,111,109,112,111,110,101,110,
+116,115, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 1, 45, 0, 0, 1, 45, 0,
+ 0, 1, 45, 0, 0, 1, 45, 0, 0, 1, 45, 0, 0, 1, 45, 0, 0, 1, 45, 0,
+ 0, 1, 46, 0, 0, 1, 46, 0, 0, 1, 46, 0, 0, 1, 46, 0, 0, 1, 46, 0,
+ 0, 1, 47, 0, 0, 1, 48, 0, 0, 0, 2, 0, 0, 0, 15,115,114, 99, 95,105,
+109, 97,103,101, 95,108,105,115,116, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0, 10,100,115,116, 95,105,109, 97,103,101, 0, 0, 0, 0, 7, 0, 0, 0, 13,
+ 0, 0, 0, 0, 0, 0, 1,144, 0, 0, 0, 25, 0, 0, 0, 50, 0, 0, 0, 73,
+ 0, 0, 0, 97, 0, 0, 0,122, 0, 0, 0,130, 0, 0, 0,132, 0, 0, 0,132,
+ 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,133,
+ 0, 0, 0,133, 0, 0, 0,133, 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,134,
+ 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0,136,
+ 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136,
+ 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0,137, 0, 0, 0,137,
+ 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138,
+ 0, 0, 0,138, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139,
+ 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,141, 0, 0, 0,144,
+ 0, 0, 0,141, 0, 0, 0,146, 0, 0, 0,149, 0, 0, 0,146, 0, 0, 0,151,
+ 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,152, 0, 0, 0,151, 0, 0, 0,154,
+ 0, 0, 0,160, 0, 0, 0,154, 0, 0, 0,162, 0, 0, 0,162, 0, 0, 0,162,
+ 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0,164, 0, 0, 0,172, 0, 0, 0,176,
+ 0, 0, 0,172, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,179,
+ 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,180,
+ 0, 0, 0,180, 0, 0, 0,180, 0, 0, 0,181, 0, 0, 0,181, 0, 0, 0,181,
+ 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,183, 0, 0, 0,183,
+ 0, 0, 0,183, 0, 0, 0,184, 0, 0, 0,184, 0, 0, 0,184, 0, 0, 0,185,
+ 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,186, 0, 0, 0,186,
+ 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,188, 0, 0, 0,188,
+ 0, 0, 0,188, 0, 0, 0,189, 0, 0, 0,189, 0, 0, 0,189, 0, 0, 0,190,
+ 0, 0, 0,190, 0, 0, 0,190, 0, 0, 0,191, 0, 0, 0,191, 0, 0, 0,191,
+ 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,193, 0, 0, 0,193,
+ 0, 0, 0,193, 0, 0, 0,194, 0, 0, 0,194, 0, 0, 0,194, 0, 0, 0,195,
+ 0, 0, 0,195, 0, 0, 0,195, 0, 0, 0,196, 0, 0, 0,196, 0, 0, 0,196,
+ 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,198, 0, 0, 0,198,
+ 0, 0, 0,198, 0, 0, 0,199, 0, 0, 0,199, 0, 0, 0,199, 0, 0, 0,200,
+ 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,201, 0, 0, 0,201, 0, 0, 0,201,
+ 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,203, 0, 0, 0,203,
+ 0, 0, 0,203, 0, 0, 0,204, 0, 0, 0,204, 0, 0, 0,204, 0, 0, 0,205,
+ 0, 0, 0,205, 0, 0, 0,205, 0, 0, 0,206, 0, 0, 0,206, 0, 0, 0,206,
+ 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,208, 0, 0, 0,208,
+ 0, 0, 0,208, 0, 0, 0,209, 0, 0, 0,209, 0, 0, 0,209, 0, 0, 0,210,
+ 0, 0, 0,210, 0, 0, 0,210, 0, 0, 0,211, 0, 0, 0,211, 0, 0, 0,211,
+ 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212,
+ 0, 0, 0,214, 0, 0, 0,227, 0, 0, 0,214, 0, 0, 0,235, 0, 0, 0,237,
+ 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,238,
+ 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,239,
+ 0, 0, 0,239, 0, 0, 0,239, 0, 0, 0,240, 0, 0, 0,240, 0, 0, 0,240,
+ 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,242, 0, 0, 0,242,
+ 0, 0, 0,242, 0, 0, 0,243, 0, 0, 0,243, 0, 0, 0,243, 0, 0, 0,244,
+ 0, 0, 0,244, 0, 0, 0,244, 0, 0, 0,245, 0, 0, 0,245, 0, 0, 0,245,
+ 0, 0, 0,246, 0, 0, 0,246, 0, 0, 0,246, 0, 0, 0,247, 0, 0, 0,247,
+ 0, 0, 0,247, 0, 0, 0,248, 0, 0, 0,248, 0, 0, 0,248, 0, 0, 0,250,
+ 0, 0, 0,254, 0, 0, 0,250, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0,
+ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 1, 2,
+ 0, 0, 1, 2, 0, 0, 1, 3, 0, 0, 1, 3, 0, 0, 1, 3, 0, 0, 1, 3,
+ 0, 0, 1, 3, 0, 0, 1, 3, 0, 0, 1, 5, 0, 0, 1, 9, 0, 0, 1, 5,
+ 0, 0, 1, 11, 0, 0, 1, 15, 0, 0, 1, 11, 0, 0, 1, 17, 0, 0, 1, 17,
+ 0, 0, 1, 17, 0, 0, 1, 18, 0, 0, 1, 18, 0, 0, 1, 18, 0, 0, 1, 19,
+ 0, 0, 1, 19, 0, 0, 1, 19, 0, 0, 1, 19, 0, 0, 1, 19, 0, 0, 1, 19,
+ 0, 0, 1, 19, 0, 0, 1, 20, 0, 0, 1, 20, 0, 0, 1, 20, 0, 0, 1, 21,
+ 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 22, 0, 0, 1, 22, 0, 0, 1, 22,
+ 0, 0, 1, 24, 0, 0, 1, 29, 0, 0, 1, 24, 0, 0, 1, 31, 0, 0, 1, 31,
+ 0, 0, 1, 31, 0, 0, 1, 31, 0, 0, 1, 31, 0, 0, 1, 31, 0, 0, 1, 31,
+ 0, 0, 1, 31, 0, 0, 1, 32, 0, 0, 1, 32, 0, 0, 1, 32, 0, 0, 1, 32,
+ 0, 0, 1, 32, 0, 0, 1, 32, 0, 0, 1, 32, 0, 0, 1, 32, 0, 0, 1, 34,
+ 0, 0, 1, 42, 0, 0, 1, 34, 0, 0, 1, 44, 0, 0, 1, 48, 0, 0, 1, 44,
+ 0, 0, 1, 50, 0, 0, 1, 50, 0, 0, 1, 50, 0, 0, 1, 50, 0, 0, 1, 50,
+ 0, 0, 1, 50, 0, 0, 1, 51, 0, 0, 1, 51, 0, 0, 1, 51, 0, 0, 1, 52,
+ 0, 0, 1, 52, 0, 0, 1, 52, 0, 0, 1, 53, 0, 0, 1, 53, 0, 0, 1, 53,
+ 0, 0, 1, 54, 0, 0, 1, 54, 0, 0, 1, 54, 0, 0, 1, 55, 0, 0, 1, 55,
+ 0, 0, 1, 55, 0, 0, 1, 56, 0, 0, 1, 56, 0, 0, 1, 56, 0, 0, 1, 57,
+ 0, 0, 1, 57, 0, 0, 1, 57, 0, 0, 1, 57, 0, 0, 1, 57, 0, 0, 1, 57,
+ 0, 0, 1, 58, 0, 0, 1, 58, 0, 0, 1, 58, 0, 0, 1, 58, 0, 0, 1, 58,
+ 0, 0, 1, 58, 0, 0, 1, 59, 0, 0, 1, 59, 0, 0, 1, 59, 0, 0, 1, 60,
+ 0, 0, 1, 60, 0, 0, 1, 60, 0, 0, 1, 60, 0, 0, 1, 60, 0, 0, 1, 60,
+ 0, 0, 1, 60, 0, 0, 1, 61, 0, 0, 1, 61, 0, 0, 1, 61, 0, 0, 1, 61,
+ 0, 0, 1, 61, 0, 0, 1, 61, 0, 0, 1, 61, 0, 0, 1, 62, 0, 0, 1, 62,
+ 0, 0, 1, 62, 0, 0, 1, 62, 0, 0, 1, 62, 0, 0, 1, 62, 0, 0, 1, 62,
+ 0, 0, 1, 63, 0, 0, 1, 63, 0, 0, 1, 63, 0, 0, 1, 64, 0, 0, 1, 64,
+ 0, 0, 1, 64, 0, 0, 1, 64, 0, 0, 1, 64, 0, 0, 1, 64, 0, 0, 1, 64,
+ 0, 0, 1, 65, 0, 0, 1, 65, 0, 0, 1, 65, 0, 0, 1, 65, 0, 0, 1, 65,
+ 0, 0, 1, 65, 0, 0, 1, 65, 0, 0, 1, 66, 0, 0, 1, 66, 0, 0, 1, 66,
+ 0, 0, 1, 67, 0, 0, 1, 67, 0, 0, 1, 67, 0, 0, 1, 68, 0, 0, 1, 68,
+ 0, 0, 1, 68, 0, 0, 1, 69, 0, 0, 1, 69, 0, 0, 1, 69, 0, 0, 1, 69,
+ 0, 0, 1, 69, 0, 0, 1, 69, 0, 0, 1, 69, 0, 0, 1, 70, 0, 0, 1, 70,
+ 0, 0, 1, 70, 0, 0, 1, 70, 0, 0, 1, 70, 0, 0, 1, 70, 0, 0, 1, 70,
+ 0, 0, 1, 71, 0, 0, 1, 71, 0, 0, 1, 71, 0, 0, 1, 72, 0, 0, 1, 72,
+ 0, 0, 1, 72, 0, 0, 1, 72, 0, 0, 0, 7, 0, 0, 0, 17, 79,110,101, 83,
+111,117,114, 99,101, 79,110,101, 68,101,115,116, 0, 0, 0, 0, 1, 0, 0, 1,
+143, 0, 0, 0, 18, 84,119,111, 83,111,117,114, 99,101,115, 79,110,101, 68,101,
+115,116, 0, 0, 0, 0, 2, 0, 0, 1,143, 0, 0, 0, 20, 84,104,114,101,101,
+ 83,111,117,114, 99,101,115, 79,110,101, 68,101,115,116, 0, 0, 0, 0, 3, 0,
+ 0, 1,143, 0, 0, 0, 18, 79,110,101, 83,111,117,114, 99,101, 84,119,111, 68,
+101,115,116,115, 0, 0, 0, 0, 4, 0, 0, 1,143, 0, 0, 0, 20, 79,110,101,
+ 83,111,117,114, 99,101, 84,104,114,101,101, 68,101,115,116,115, 0, 0, 0, 0,
+ 5, 0, 0, 1,143, 0, 0, 0, 13,104,111,117,103,104, 95,104,101,105,103,104,
+116, 0, 0, 0, 0, 6, 0, 0, 1,143, 0, 0, 0, 13,105,110,116, 95,100, 97,
+116, 97,116,121,112,101, 0, 0, 0, 0,182, 0, 0, 1,143, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_process51/im_process_be32.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_process_be64.loh b/im/src/lua5/loh/im_process_be64.loh
new file mode 100644
index 0000000..ee881bb
--- /dev/null
+++ b/im/src/lua5/loh/im_process_be64.loh
@@ -0,0 +1,897 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_process51/im_process_be64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_process51/im_process_be64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,112,114,111, 99,101,115,115, 46,108,117, 97,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13,144, 1, 0, 0, 36, 0, 0,
+ 0,100, 64, 0, 0,164,128, 0, 0,228,192, 0, 0, 36, 1, 1, 0,100, 65, 1,
+ 0,128, 1, 0, 0,193, 1, 0, 0, 3, 2, 0, 5,197, 66, 0, 0,198,130,192,
+ 5,156, 65, 0, 3,128, 1, 0, 0,193,193, 0, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 1, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 1, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 1, 0, 1,194, 1, 0, 64, 2,128, 2,133, 66, 0,
+ 0,134, 2, 66, 5,197, 66, 0, 0,198, 66,194, 5,156, 65, 0, 3,128, 1, 0,
+ 0,193,129, 2, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 2, 0, 3, 2, 0,
+ 5,197, 66, 0, 0,198, 2,195, 5,156, 65, 0, 3,128, 1, 0, 0,193, 65, 3,
+ 0, 3, 2,128, 4,133, 66, 0, 0,134,130, 67, 5,195, 2,128, 5,156, 65, 0,
+ 3,133, 65, 0, 0,228,129, 1, 0,137,193,129,135,133, 65, 0, 0,228,193, 1,
+ 0,137,193, 1,136,128, 1, 0, 0,193, 65, 4, 0, 36, 2, 2, 0,100, 66, 2,
+ 0,156, 65, 0, 2,133, 65, 0, 0,228,129, 2, 0,137,193, 1,137,128, 1,128,
+ 0,193,193, 4, 0,156, 65, 0, 1,133, 65, 0, 0,228,193, 2, 0,137,193, 1,
+138,133, 65, 0, 0,228, 1, 3, 0,137,193,129,138,128, 1, 0, 0,193,129, 5,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 5, 0, 36, 66, 3, 0,100,130, 3,
+ 0,156, 65, 0, 2,128, 1, 0, 0,193, 1, 6, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 65, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 6, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 7,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 7, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 7, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 7, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 1, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 8,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 8, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 9, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 65, 9, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 9,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 9, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 10, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 10, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 10, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 10,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 11, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 65, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 11, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 12,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 12, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 12, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 12, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 1, 13, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 13,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 13, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 13, 0,156, 65, 0, 1,128, 1,128, 1,193, 1, 14, 0, 3, 2, 0,
+ 4,100,194, 3, 0,156, 65, 0, 2,133, 65, 0, 0,228, 1, 4, 0,137,193,129,
+156,164, 65, 4, 0,192, 1, 0, 0, 1,130, 14, 0, 67, 2,128, 5, 0, 3, 0,
+ 3,220, 65, 0, 3,192, 1, 0, 0, 1,194, 14, 0, 67, 2,128, 5, 0, 3, 0,
+ 3,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 15, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 66, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 15, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,194, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 16,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 16, 0,220, 65, 0, 1,192, 1,128,
+ 0, 1,130, 16, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 16, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 2, 17, 0,220, 65, 0, 1,192, 1,128, 0, 1, 66, 17,
+ 0,220, 65, 0, 1,197, 65, 0, 0, 36,130, 4, 0,201, 1, 2,163,192, 1,128,
+ 0, 1,194, 17, 0,220, 65, 0, 1,192, 1, 0, 1, 1, 2, 18, 0,220, 65, 0,
+ 1,192, 1,128, 1, 1, 66, 18, 0,220, 65, 0, 1,192, 1,128, 0, 1,130, 18,
+ 0, 67, 2,128, 5, 5, 67, 0, 0, 6,195, 82, 6,220, 65, 0, 3,197, 65, 0,
+ 0, 36,194, 4, 0,201, 1, 2,166,197, 65, 0, 0, 36, 2, 5, 0,201, 1,130,
+166,192, 1,128, 0, 1,130, 19, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 19,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 20, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198, 66,212, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,130, 20,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 20, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 2, 21, 0,220, 65, 0, 1,197, 65, 0, 0, 36, 66, 5, 0,201, 1,130,
+170,192, 1, 0, 2, 1,130, 21, 0, 67, 2, 0, 5,197, 66, 0, 0,198, 2,194,
+ 5, 5, 67, 0, 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0, 1, 1,194, 21,
+ 0, 67, 2, 0, 5,197, 66, 0, 0,198, 2,214, 5, 5, 67, 0, 0, 6, 67, 86,
+ 6,220, 65, 0, 3,197, 65, 0, 0, 36,130, 5, 0,201, 1, 2,173,197, 65, 0,
+ 0, 36,194, 5, 0,201, 1,130,173,192, 1, 0, 0, 1, 2, 23, 0, 67, 2,128,
+ 5, 5, 67, 0, 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 23,
+ 0,220, 65, 0, 1,192, 1,128, 0, 1,130, 23, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1,194, 23, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 24, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 66, 24, 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 24,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 24, 0, 67, 2,128, 5, 5, 67, 0,
+ 0, 6, 67, 86, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 25, 0, 67, 2,128,
+ 5, 5, 67, 0, 0, 6, 67, 86, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 25,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 25, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,194, 25,
+ 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0,
+ 3,192, 1, 0, 0, 1, 2, 26, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1,128, 0, 1, 66, 26, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,130, 26, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,194, 26, 0, 67, 2, 0,
+ 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1, 2, 27, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 27, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,130, 27, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 27,
+ 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0,
+ 3,192, 1, 0, 0, 1, 2, 28, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 28, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,130, 28, 0,220, 65, 0, 1, 30, 0,128, 0,115, 0, 0,
+ 0, 4, 19, 0, 0, 0, 0, 0, 0, 0, 65,110, 97,108,121,122,101, 70,105,110,
+100, 82,101,103,105,111,110,115, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 85, 83, 72, 79, 82, 84, 0, 4, 21, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114,105,109,101,116,
+101,114, 76,105,110,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 82,101,109,111,118,101, 66,121, 65,114,101, 97, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 70,105,108,108, 72,111,108,101,
+115, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 72,111,
+117,103,104, 76,105,110,101,115, 0, 3, 0, 0, 0, 0, 0,128,102, 64, 4, 5,
+ 0, 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 73, 78, 84, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 72,111,117,103,104, 76,105,110,101,115, 68,114, 97,119, 0, 4, 25, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 68,105,115,116, 97,110, 99,101,
+ 84,114, 97,110,115,102,111,114,109, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 70,
+ 76, 79, 65, 84, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,101,103,105,111,110, 97,108, 77, 97,120,105,109,117,109, 0, 4, 7, 0,
+ 0, 0, 0, 0, 0, 0, 66, 73, 78, 65, 82, 89, 0, 4, 17, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 82,101,100,117, 99,101, 78,101,119, 0, 4,
+ 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,115,105,122,
+101, 78,101,119, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,101,100,117, 99,101, 66,121, 52, 0, 4, 15, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 67,114,111,112, 78,101,119, 0, 4, 14, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,115,101,114,116, 0, 4, 21,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,100,100, 77, 97,114,
+103,105,110,115, 78,101,119, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 82,111,116, 97,116,101, 78,101,119, 0, 4, 17, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,116, 97,116,101, 82,101,102, 0,
+ 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,116, 97,
+116,101, 57, 48, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,111,116, 97,116,101, 49, 56, 48, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 77,105,114,114,111,114, 0, 4, 12, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 70,108,105,112, 0, 4, 14, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,100,105, 97,108, 0, 4, 25,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,
+114,112,104, 67,111,110,118,111,108,118,101, 0, 4, 22, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 69,114,111,
+100,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,
+114, 97,121, 77,111,114,112,104, 68,105,108, 97,116,101, 0, 4, 21, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104,
+ 79,112,101,110, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 71,114, 97,121, 77,111,114,112,104, 67,108,111,115,101, 0, 4, 23, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,
+104, 84,111,112, 72, 97,116, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 87,101,108,108, 0, 4, 25,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,
+114,112,104, 71,114, 97,100,105,101,110,116, 0, 4, 24, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,111,110,118,
+111,108,118,101, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 66,105,110, 77,111,114,112,104, 69,114,111,100,101, 0, 4, 22, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 68,
+105,108, 97,116,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 66,105,110, 77,111,114,112,104, 79,112,101,110, 0, 4, 21, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,
+108,111,115,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 66,105,110, 77,111,114,112,104, 79,117,116,108,105,110,101, 0, 4, 20, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,
+104, 84,104,105,110, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 77,101,100,105, 97,110, 67,111,110,118,111,108,118,101, 0, 4, 21, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,111,
+110,118,111,108,118,101, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 82, 97,110,107, 67,108,111,115,101,115,116, 67,111,110,118,111,108,
+118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,
+ 97,110,107, 77, 97,120, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,107, 77,105,110, 67,111,
+110,118,111,108,118,101, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 67,111,110,118,111,108,118,101, 0, 4, 19, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101, 83,101,112, 0,
+ 4, 19, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,110,118,
+111,108,118,101, 82,101,112, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 67,111,110,118,111,108,118,101, 68,117, 97,108, 0, 4, 23, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,109,112, 97,115,115,
+ 67,111,110,118,111,108,118,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 77,101, 97,110, 67,111,110,118,111,108,118,101, 0, 4, 24,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71, 97,117,115,115,105,
+ 97,110, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 66, 97,114,108,101,116,116, 67,111,110,118,111,108,
+118,101, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,
+110,116,101,114,108, 97, 99,101, 83,112,108,105,116, 0, 4, 25, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,116,101,114,108, 97, 99,101, 83,
+112,108,105,116, 78,101,119, 0, 4, 30, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 68,105,102,102, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,
+110,118,111,108,118,101, 0, 4, 29, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 76, 97,112, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,110,118,
+111,108,118,101, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 83,111, 98,101,108, 67,111,110,118,111,108,118,101, 0, 4, 26, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,110,101, 69,100,103,
+101, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 80,114,101,119,105,116,116, 67,111,110,118,111,108,118,
+101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 90,101,
+114,111, 67,114,111,115,115,105,110,103, 0, 4, 13, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 67, 97,110,110,121, 0, 4, 22, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 85,110, 65,114,105,116,104,109,101,116,105,
+ 99, 79,112, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 65,114,105,116,104,109,101,116,105, 99, 79,112, 0, 4, 15, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 85,110,115,104, 97,114,112, 0, 4, 13, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,104, 97,114,112, 0, 4,
+ 19, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,104, 97,114,112,
+ 75,101,114,110,101,108, 0, 4, 28, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 65,114,105,116,104,109,101,116,105, 99, 67,111,110,115,116, 79,112,
+ 78,101,119, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 66,108,101,110,100, 67,111,110,115,116, 0, 4, 13, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 66,108,101,110,100, 0, 4, 20, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,108,101,
+120, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,101,
+114,103,101, 67,111,109,112,108,101,120, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,
+ 67, 70, 76, 79, 65, 84, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 77,117,108,116,105,112,108,101, 77,101, 97,110, 78,101,119, 0, 4,
+ 25, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,117,108,116,105,
+112,108,101, 83,116,100, 68,101,118, 78,101,119, 0, 4, 22, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 65,117,116,111, 67,111,118, 97,114,105, 97,
+110, 99,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 77,117,108,116,105,112,108,121, 67,111,110,106, 0, 4, 26, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 81,117, 97,110,116,105,122,101, 82, 71, 66,
+ 85,110,105,102,111,114,109, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 77, 65, 80,
+ 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 81,117, 97,
+110,116,105,122,101, 71,114, 97,121, 85,110,105,102,111,114,109, 0, 4, 23, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 69,120,112, 97,110,100, 72,
+105,115,116,111,103,114, 97,109, 0, 4, 25, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 69,113,117, 97,108,105,122,101, 72,105,115,116,111,103,114,
+ 97,109, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,
+112,108,105,116, 89, 67,104,114,111,109, 97, 78,101,119, 0, 4, 16, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 72, 83, 73, 0,
+ 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,101,114,103,
+101, 72, 83, 73, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 82, 71, 66, 0, 4, 5,
+ 0, 0, 0, 0, 0, 0, 0, 66, 89, 84, 69, 0, 4, 26, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,111,110,101,
+110,116,115, 78,101,119, 0, 4, 26, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 77,101,114,103,101, 67,111,109,112,111,110,101,110,116,115, 78,101,
+119, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 78,111,
+114,109, 97,108,105,122,101, 67,111,109,112,111,110,101,110,116,115, 0, 4, 20,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,112,108, 97, 99,
+101, 67,111,108,111,114, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 66,105,116,119,105,115,101, 79,112, 0, 4, 18, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 66,105,116,119,105,115,101, 78,111,116, 0,
+ 4, 15, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,116, 77,
+ 97,115,107, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 66,105,116, 80,108, 97,110,101, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 84,111,110,101, 71, 97,109,117,116, 0, 4, 19, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 85,110, 78,111,114,109, 97,108,105,
+122,101, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 68,
+105,114,101, 99,116, 67,111,110,118, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 78,101,103, 97,116,105,118,101, 0, 4, 30, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,111,110,116,
+114, 97,115,116, 84,104,114,101,115,104,111,108,100, 0, 4, 25, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 76,111, 99, 97,108, 77, 97,120, 84,104,
+114,101,115,104,111,108,100, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 84,104,114,101,115,104,111,108,100, 0, 4, 23, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 84,104,114,101,115,104,111,108,100, 66,
+121, 68,105,102,102, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 72,121,115,116,101,114,101,115,105,115, 84,104,114,101,115,104,111,108,
+100, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 85,110,
+105,102,111,114,109, 69,114,114, 84,104,114,101,115,104,111,108,100, 0, 4, 28,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 68,105,102,117,115,105,
+111,110, 69,114,114, 84,104,114,101,115,104,111,108,100, 0, 4, 24, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114, 99,101,110,116, 84,104,
+114,101,115,104,111,108,100, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 79,116,115,117, 84,104,114,101,115,104,111,108,100, 0, 4, 23,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,105,110, 77, 97,120,
+ 84,104,114,101,115,104,111,108,100, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 83,108,105, 99,101, 84,104,114,101,115,104,111,108,100,
+ 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,105,120,
+101,108, 97,116,101, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 80,111,115,116,101,114,105,122,101, 0, 24, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 25, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0,
+ 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,
+133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0,
+ 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,
+137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0,
+ 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0,
+ 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 5, 1, 7, 8, 23, 0, 0,
+ 0,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128,
+ 0,132, 1, 0, 1,196, 1,128, 1,156,128, 0, 3,196, 0, 0, 2, 0, 1, 0,
+ 0, 64, 1, 0, 1,133,129, 0, 0,192, 1,128, 0,156, 1, 0, 1,220,128, 0,
+ 0,218, 0, 0, 0, 22,192, 0,128, 0, 1,128, 1, 64, 1, 0, 1, 30, 1,128,
+ 1, 22, 0, 0,128,158, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0,
+ 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109,
+ 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,
+ 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 23, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 19,
+ 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20,
+ 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 22, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 22, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8,
+ 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 15,
+ 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,
+105,100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0,
+ 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25,
+ 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110,
+ 97,109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+119,105,100,116,104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0,
+ 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,
+112,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,
+117,110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 31, 0, 0, 0, 50, 0, 0, 0, 0, 5, 0, 11, 22, 0, 0, 0,
+ 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2, 5,130, 0, 0,
+ 6,194, 64, 4, 65, 2, 1, 0,128, 2, 0, 0, 28, 2,128, 1,156, 65, 0, 0,
+133, 1, 0, 0,192, 1, 0, 0, 1, 66, 1, 0,213, 1,130, 3, 36, 2, 0, 0,
+ 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,
+137, 1,130, 3, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0,
+ 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0,115,116,114,105,110,103, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0,102,111,114,109, 97,116, 0, 4, 24, 0, 0, 0, 0, 0, 0,
+ 0,117,110,100,101,102,105,110,101,100, 32,102,117,110, 99,116,105,111,110, 32,
+ 96, 37,115, 39, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 5, 2,
+ 7, 10, 24, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1,
+ 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1,
+ 0, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 5,130, 0, 0, 64, 2,
+ 0, 1, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22,192, 0,128, 64, 1,
+ 0, 2,128, 1,128, 1, 94, 1,128, 1, 22, 0, 0,128,222, 0, 0, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17,
+ 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,
+115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0,
+ 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0,
+ 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0,
+ 49, 0, 0, 0, 5, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,
+105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 23, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0,
+ 8, 0, 0, 0, 23, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0,
+ 16, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+119,105,100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 22, 0, 0, 0, 32, 0, 0, 0,
+ 32, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 0,
+ 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 50, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,
+110, 97,109,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+ 0,119,105,100,116,104, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0,
+ 0, 0, 21, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,
+121,112,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+102,117,110, 99, 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 56, 0, 0, 0, 73, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0,
+ 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0,
+ 1,133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0,
+ 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128,
+ 2,137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0,
+ 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116,
+ 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 72, 0, 0, 0, 5, 3, 7, 12, 25, 0,
+ 0, 0, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0, 0,196, 1,
+128, 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0, 2,128, 1,
+ 0, 0,192, 1,128, 0, 0, 2, 0, 1, 64, 2, 0, 2,133,130, 0, 0,192, 2,
+128, 1,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22,192, 0,128,128, 1,
+128, 2,192, 1, 0, 2,158, 1,128, 1, 22, 0, 0,128, 30, 1, 0, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17,
+ 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,
+115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
+ 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
+ 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0,
+ 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0,
+ 67, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0,
+ 70, 0, 0, 0, 72, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,
+115,114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 24, 0, 0, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0,
+ 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109,
+ 97,103,101, 51, 0, 0, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 97,114,103, 0, 0, 0, 0, 0, 24, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 24, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 17, 0, 0, 0, 24, 0, 0, 0, 5,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,
+110, 99, 0, 17, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 58, 0, 0, 0, 58,
+ 0, 0, 0, 58, 0, 0, 0, 61, 0, 0, 0, 61, 0, 0, 0, 61, 0, 0, 0, 61,
+ 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72,
+ 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 73, 0, 0, 0, 6, 0, 0, 0, 9,
+ 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,
+111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0,
+ 97, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,
+133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0,
+ 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1,
+ 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0,
+ 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0,
+ 0, 96, 0, 0, 0, 5, 1, 7, 10, 35, 0, 0, 0,133, 0, 0, 0,134, 64, 64,
+ 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0, 1,196, 1,128,
+ 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1, 0,
+ 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1, 0,
+ 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1, 5,130, 0, 0, 64, 2,128,
+ 0, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22, 0, 1,128, 64, 1, 0,
+ 2,128, 1, 0, 1,192, 1,128, 1, 94, 1, 0, 2, 22,128, 0,128, 64, 1, 0,
+ 1,128, 1,128, 1, 94, 1,128, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0,
+ 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109,
+ 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,
+ 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 35, 0, 0, 0, 86,
+ 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86,
+ 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87,
+ 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87,
+ 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90,
+ 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 91,
+ 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92,
+ 0, 0, 0, 94, 0, 0, 0, 94, 0, 0, 0, 94, 0, 0, 0, 96, 0, 0, 0, 5,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103,
+ 0, 0, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116,
+ 95,105,109, 97,103,101, 49, 0, 8, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0,
+ 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 50, 0, 16, 0, 0, 0, 34,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 24, 0, 0, 0, 34,
+ 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104,
+ 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0,
+ 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 81,
+ 0, 0, 0, 81, 0, 0, 0, 81, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84,
+ 0, 0, 0, 84, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96,
+ 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 97, 0, 0, 0, 6,
+ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,
+104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,
+105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0,
+ 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0,
+ 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+103, 0, 0, 0,122, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0,
+ 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,
+192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0,
+ 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3,
+ 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0,
+ 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,108, 0, 0, 0,121, 0, 0, 0, 5, 1, 7, 12, 46, 0, 0, 0,133, 0, 0,
+ 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0,
+ 1,196, 1,128, 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0,
+ 0, 68, 1, 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0,
+ 3, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0, 0,196, 1,128,
+ 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0, 2,128, 1, 0,
+ 0,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,133,130, 0, 0,192, 2,128,
+ 0,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22, 64, 1,128,128, 1,128,
+ 2,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,158, 1,128, 2, 22,192, 0,
+128,128, 1, 0, 1,192, 1,128, 1, 0, 2, 0, 2,158, 1, 0, 2, 30, 0,128,
+ 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0,
+ 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,
+101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 46, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110,
+ 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,111,
+ 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111,
+ 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112,
+ 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112,
+ 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115,
+ 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,116,
+ 0, 0, 0,116, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117,
+ 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,119, 0, 0, 0,119, 0, 0, 0,119,
+ 0, 0, 0,119, 0, 0, 0,121, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 45, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 45, 0, 0,
+ 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 49, 0,
+ 8, 0, 0, 0, 45, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,
+105,109, 97,103,101, 50, 0, 16, 0, 0, 0, 45, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 51, 0, 24, 0, 0, 0, 45, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 33, 0, 0, 0, 45, 0,
+ 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0,
+ 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0,102,117,110, 99, 0, 17, 0, 0, 0,104, 0, 0, 0,104, 0, 0, 0,105, 0,
+ 0, 0,105, 0, 0, 0,105, 0, 0, 0,108, 0, 0, 0,108, 0, 0, 0,108, 0,
+ 0, 0,108, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0,
+ 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,122, 0, 0, 0, 6, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,
+103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2,
+ 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126,
+ 0, 0, 0,130, 0, 0, 0, 0, 1, 0, 7, 18, 0, 0, 0,100, 0, 0, 0,133,
+ 0, 0, 0,134, 64, 64, 1,192, 0,128, 0, 11,129, 64, 0, 28, 1, 0, 1,220,
+128, 0, 0, 0, 1,128, 0, 75,193, 64, 0, 92, 1, 0, 1, 28,129, 0, 0,204,
+ 0,129, 1,156,128, 0, 1,143, 0, 65, 1,206,128, 0,130,204, 64,193, 1,222,
+ 0, 0, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,
+109, 97,116,104, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,115,113,114,116, 0, 4,
+ 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 3,
+ 0, 0, 0, 0, 0, 0,240, 63, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+127, 0, 0, 0,127, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 78, 0, 0, 0,
+ 94, 0, 0, 1, 30, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+127, 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0,120, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 18, 0,
+ 0, 0,127, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0,
+ 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0,
+ 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,129, 0,
+ 0, 0,129, 0, 0, 0,129, 0, 0, 0,130, 0, 0, 0, 3, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 17, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0,115,113,114, 0, 1, 0, 0, 0, 17, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 0, 0,114,109, 97,120, 0, 14, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,141, 0, 0, 0,144, 0, 0,
+ 0, 0, 3, 0, 7, 14, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0,
+ 0, 64, 1,128, 0,128, 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0, 6,129, 64,
+ 2, 64, 1, 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30, 1,128,
+ 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 82,101,100,117, 99,101, 0, 0, 0, 0, 0, 14, 0, 0, 0,142, 0,
+ 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0,
+ 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0,
+ 0, 0,143, 0, 0, 0,143, 0, 0, 0,144, 0, 0, 0, 4, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116,
+ 95,105,109, 97,103,101, 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,146, 0, 0, 0,149, 0, 0, 0, 0, 3, 0, 7, 14,
+ 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 64, 1,128, 0,128,
+ 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0, 6,129, 64, 2, 64, 1, 0, 0,128,
+ 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,128, 0, 3,
+ 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0,
+ 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,115,
+105,122,101, 0, 0, 0, 0, 0, 14, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,
+147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,148, 0, 0, 0,
+148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,
+148, 0, 0, 0,149, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 13, 0, 0, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 13,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101,
+ 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,151, 0, 0, 0,151, 0, 0, 0, 0, 1, 0, 3, 5, 0, 0, 0, 75, 0, 64,
+ 0, 92,128, 0, 1, 79, 64,192, 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0,
+ 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 64, 0, 0, 0, 0, 5, 0, 0, 0,151, 0, 0, 0,151, 0, 0,
+ 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0, 0,
+ 1, 0, 3, 5, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1, 79, 64,192, 0, 94,
+ 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,
+ 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0,
+ 5, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,
+152, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,
+101, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,154, 0, 0, 0,160, 0, 0, 0, 0, 5, 0, 13, 19, 0, 0, 0, 77, 65,
+ 0, 1, 76, 1,192, 2,141,193, 0, 2,140, 1, 64, 3,197, 65, 0, 0,198,129,
+192, 3, 0, 2, 0, 0, 64, 2,128, 2,128, 2, 0, 3,220,129, 0, 2, 5, 66,
+ 0, 0, 6,194, 64, 4, 64, 2, 0, 0,128, 2,128, 3,192, 2,128, 0, 0, 3,
+128, 1, 28, 66,128, 2,222, 1, 0, 1, 30, 0,128, 0, 4, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4,
+ 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66,
+ 97,115,101,100, 0, 4, 12, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 67,114,111,112, 0, 0, 0, 0, 0, 19, 0, 0, 0,155, 0, 0, 0,155, 0,
+ 0, 0,156, 0, 0, 0,156, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0,
+ 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0,158, 0,
+ 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0,
+ 0, 0,159, 0, 0, 0,160, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 18, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 0, 0,120,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0,120,109, 97,120, 0, 0, 0, 0, 0, 18, 0,
+ 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,121,109,105,110, 0, 0, 0, 0, 0, 18,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,121,109, 97,120, 0, 0, 0, 0, 0,
+ 18, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 2, 0,
+ 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 4, 0, 0, 0, 18, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116,
+ 95,105,109, 97,103,101, 0, 10, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0, 0, 5, 0, 13, 19,
+ 0, 0, 0, 77, 65, 0, 1, 76, 1,192, 2,141,193, 0, 2,140, 1, 64, 3,197,
+ 65, 0, 0,198,129,192, 3, 0, 2, 0, 0, 64, 2,128, 2,128, 2, 0, 3,220,
+129, 0, 2, 5, 66, 0, 0, 6,194, 64, 4, 64, 2, 0, 0,128, 2,128, 3,192,
+ 2,128, 0, 0, 3,128, 1, 28, 66,128, 2,222, 1, 0, 1, 30, 0,128, 0, 4,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0, 0, 0, 0, 0,
+ 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,
+101, 97,116,101, 66, 97,115,101,100, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 65,100,100, 77, 97,114,103,105,110,115, 0, 0, 0, 0,
+ 0, 19, 0, 0, 0,165, 0, 0, 0,165, 0, 0, 0,166, 0, 0, 0,166, 0, 0,
+ 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0,
+ 0,167, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0,
+ 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 0,
+ 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,
+103,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,120,
+109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+120,109, 97,120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0,121,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0,121,109, 97,120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0,119,105,100,116,104, 0, 2, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 4, 0, 0, 0, 18, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 10, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0,
+ 0, 0,176, 0, 0, 0, 0, 4, 0, 13, 26, 0, 0, 0, 5, 1, 0, 0, 6, 65,
+ 64, 2, 75,129, 64, 0, 92,129, 0, 1,139,193, 64, 0,156,129, 0, 1,192, 1,
+128, 0, 0, 2, 0, 1, 28,193,128, 2,133, 1, 0, 0,134, 1, 65, 3,192, 1,
+ 0, 0, 0, 2, 0, 2, 64, 2,128, 2,156,129, 0, 2,197, 1, 0, 0,198, 65,
+193, 3, 0, 2, 0, 0, 64, 2, 0, 3,128, 2,128, 0,192, 2, 0, 1, 0, 3,
+128, 1,220,129, 0, 3, 0, 2, 0, 3,222, 1,128, 1, 30, 0,128, 0, 6, 0,
+ 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 22, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 67, 97,108, 99, 82,111,116, 97,116,101,
+ 83,105,122,101, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,
+100, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,
+116, 97,116,101, 0, 0, 0, 0, 0, 26, 0, 0, 0,173, 0, 0, 0,173, 0, 0,
+ 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0,
+ 0,173, 0, 0, 0,173, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0,
+ 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0,175, 0, 0,
+ 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0,
+ 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,176, 0, 0, 0, 7, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0,
+ 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 99,111,115, 48, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,115,105,110, 48,
+ 0, 0, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,111,114,100,
+101,114, 0, 0, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,
+105,100,116,104, 0, 9, 0, 0, 0, 25, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+ 0,104,101,105,103,104,116, 0, 9, 0, 0, 0, 25, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 15, 0, 0, 0, 25, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0, 0, 1, 0, 3, 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0, 1, 94, 0,
+ 0, 0, 30, 0,128, 0, 1, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,
+101,105,103,104,116, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0,179, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0, 0, 1, 0, 3,
+ 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0, 1, 94, 0, 0, 0, 30, 0,128, 0,
+ 1, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179,
+ 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,212, 0, 0, 0,212, 0, 0, 0, 0, 1, 0, 3, 13, 0, 0, 0, 75, 0, 64,
+ 0, 92,128, 0, 1, 90, 0, 0, 0, 22,192, 0,128, 75, 0, 64, 0, 93, 0, 0,
+ 1, 94, 0, 0, 0, 22,192, 0,128, 75, 0, 64, 0, 92,128, 0, 1, 79, 64,192,
+ 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0,
+ 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0,
+ 0, 0, 13, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0,
+ 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0,
+ 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0, 1, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214, 0, 0, 0,
+227, 0, 0, 0, 0, 1, 0, 8, 36, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1,
+ 79, 64,192, 0,133,128, 0, 0,134,192, 64, 1,203, 0, 64, 0,220,128, 0, 1,
+ 1, 65, 0, 0,156,128,128, 1,154, 0, 0, 0, 22, 0, 0,128, 76, 0,193, 0,
+133, 64, 1, 0,134,128, 65, 1,192, 0, 0, 0, 3, 1, 0, 2, 64, 1,128, 0,
+156,128, 0, 2,197, 64, 1, 0,198,128,193, 1, 0, 1, 0, 0, 67, 1,128, 2,
+139, 1, 64, 0,156,129, 0, 1,143, 65, 64, 3,220,128, 0, 2, 5, 65, 1, 0,
+ 6,193, 65, 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1, 28, 65, 0, 2,
+ 0, 1, 0, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,128, 0, 8, 0, 0, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 64, 4, 5, 0, 0, 0, 0, 0, 0, 0,109, 97,116,104, 0, 4,
+ 4, 0, 0, 0, 0, 0, 0, 0,109,111,100, 0, 3, 0, 0, 0, 0, 0, 0,240,
+ 63, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0,
+ 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4,
+ 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,116,101,114,
+108, 97, 99,101, 83,112,108,105,116, 0, 0, 0, 0, 0, 36, 0, 0, 0,216, 0,
+ 0, 0,216, 0, 0, 0,216, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0,
+ 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0,
+ 0, 0,218, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0,
+ 0, 0,221, 0, 0, 0,221, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0,
+ 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0,
+ 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0,
+ 0, 0,225, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,227, 0,
+ 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+100,115,116, 95,104,101,105,103,104,116, 49, 0, 3, 0, 0, 0, 35, 0, 0, 0,
+ 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 49, 0, 18,
+ 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,
+109, 97,103,101, 50, 0, 26, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,229, 0, 0, 0,235, 0, 0, 0, 0, 1, 0, 3, 14, 0,
+ 0, 0, 75, 0, 64, 0, 92,128, 0, 1,133, 64, 0, 0,134,128, 64, 1, 87,128,
+128, 0, 22,192, 0,128,133, 64, 0, 0,134,192, 64, 1, 23,128,128, 0, 22, 64,
+ 0,128,133, 64, 0, 0, 70, 0, 65, 1, 94, 0, 0, 1, 30, 0,128, 0, 5, 0,
+ 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 68, 97,116, 97, 84,121,112,101, 0,
+ 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 5, 0, 0, 0, 0, 0, 0,
+ 0, 66, 89, 84, 69, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 85, 83, 72, 79, 82,
+ 84, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 73, 78, 84, 0, 0, 0, 0, 0, 14,
+ 0, 0, 0,230, 0, 0, 0,230, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231,
+ 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231,
+ 0, 0, 0,232, 0, 0, 0,232, 0, 0, 0,234, 0, 0, 0,235, 0, 0, 0, 2,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0,
+ 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,
+112,101, 0, 2, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,250, 0, 0, 0,254, 0, 0, 0, 0, 3, 0, 9, 13, 0, 0, 0,197,
+ 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0,220,128, 0, 1, 5, 1, 0, 0, 6,
+129, 64, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 0, 2, 0, 1, 28,
+ 65,128, 2,222, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 25, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 65,114,105,116,104,109,101,116,105, 99, 67,
+111,110,115,116, 79,112, 0, 0, 0, 0, 0, 13, 0, 0, 0,251, 0, 0, 0,251,
+ 0, 0, 0,251, 0, 0, 0,251, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252,
+ 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,253,
+ 0, 0, 0,254, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 12, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,115,114, 99, 95, 99,111,110,115,116, 0, 0, 0, 0, 0, 12,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,111,112, 0, 0, 0, 0, 0, 12, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0,
+ 4, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 1, 0, 0, 9, 1, 0, 0, 0, 2, 0, 6, 11, 0, 0, 0,133, 0, 0, 0,
+134, 64, 64, 1,198,128, 64, 0,156,128, 0, 1,197, 0, 0, 0,198,192,192, 1,
+ 0, 1, 0, 0, 64, 1, 0, 1,220, 64,128, 1,158, 0, 0, 1, 30, 0,128, 0,
+ 4, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,
+100, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 20, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 77,117,108,116,105,112,108,101, 77,101, 97,110, 0,
+ 0, 0, 0, 0, 11, 0, 0, 0, 6, 1, 0, 0, 6, 1, 0, 0, 6, 1, 0, 0,
+ 6, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0,
+ 7, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0,
+ 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100,115,116, 95,105,109, 97,103,101, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 1, 0, 0, 15, 1, 0, 0, 0,
+ 2, 0, 7, 12, 0, 0, 0,133, 0, 0, 0,134, 64, 64, 1,198,128, 64, 0,156,
+128, 0, 1,197, 0, 0, 0,198,192,192, 1, 0, 1, 0, 0, 64, 1,128, 0,128,
+ 1, 0, 1,220, 64, 0, 2,158, 0, 0, 1, 30, 0,128, 0, 4, 0, 0, 0, 4,
+ 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0,
+ 0, 0, 0, 0,240, 63, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 77,117,108,116,105,112,108,101, 83,116,100, 68,101,118, 0, 0, 0, 0,
+ 0, 12, 0, 0, 0, 12, 1, 0, 0, 12, 1, 0, 0, 12, 1, 0, 0, 12, 1, 0,
+ 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0,
+ 0, 13, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 3, 0, 0, 0, 15, 0, 0,
+ 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0,
+ 0, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,109,101, 97,110,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 4, 0, 0, 0, 11, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 29, 1, 0,
+ 0, 0, 1, 0, 8, 28, 0, 0, 0, 69, 0, 0, 0, 70, 64,192, 0,128, 0, 0,
+ 0,195, 0, 0, 2, 69, 1, 0, 0, 70,129,192, 2,133, 1, 0, 0,134,193, 64,
+ 3, 92,128, 0, 3,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 3, 1,128,
+ 2,133, 1, 0, 0,134, 1, 65, 3,197, 1, 0, 0,198,193,192, 3,156,128, 0,
+ 3,197, 0, 0, 0,198, 64,193, 1, 0, 1, 0, 0, 64, 1,128, 0,128, 1, 0,
+ 1,220, 64, 0, 2,192, 0,128, 0, 0, 1, 0, 1,222, 0,128, 1, 30, 0,128,
+ 0, 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0,
+ 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,
+101,100, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 5, 0,
+ 0, 0, 0, 0, 0, 0, 66, 89, 84, 69, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+ 82, 71, 66, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 83,112,108,105,116, 89, 67,104,114,111,109, 97, 0, 0, 0, 0, 0, 28, 0, 0,
+ 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0,
+ 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 26, 1, 0,
+ 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0,
+ 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0,
+ 0, 27, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0, 0, 28, 1, 0,
+ 0, 28, 1, 0, 0, 28, 1, 0, 0, 29, 1, 0, 0, 3, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 27,
+ 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,121, 95,105,109, 97,103,101, 0, 9,
+ 0, 0, 0, 27, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 99,104,114,111,109,
+ 97, 95,105,109, 97,103,101, 0, 18, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 34, 1, 0, 0, 42, 1, 0, 0, 0, 1, 0, 14,
+ 29, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1,138, 0, 0, 0,193, 64, 0, 0,
+ 0, 1,128, 0, 65, 65, 0, 0,224,128, 2,128,197,129, 0, 0,198,193,192, 3,
+ 0, 2, 0, 1, 69, 2, 1, 0, 70, 66,193, 4,128, 2, 0, 0,195, 2, 0, 6,
+ 69, 3, 1, 0, 70,131,193, 6, 92, 2,128, 2,220, 65, 0, 0,223,192,252,127,
+197, 0, 1, 0,198,192,193, 1, 0, 1, 0, 0, 64, 1, 0, 1,220, 64,128, 1,
+197, 0, 2, 0, 0, 1, 0, 1,221, 0, 0, 1,222, 0, 0, 0, 30, 0,128, 0,
+ 9, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 68,101,112,116,104, 0, 3,
+ 0, 0, 0, 0, 0, 0,240, 63, 4, 6, 0, 0, 0, 0, 0, 0, 0,116, 97, 98,
+108,101, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,105,110,115,101,114,116, 0, 4,
+ 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 5, 0,
+ 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,111,110,101,110,
+116,115, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 29, 0, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 37,
+ 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 38, 1, 0, 0, 38,
+ 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38,
+ 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 37,
+ 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 40,
+ 1, 0, 0, 41, 1, 0, 0, 41, 1, 0, 0, 41, 1, 0, 0, 41, 1, 0, 0, 42,
+ 1, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+ 0,100,101,112,116,104, 0, 2, 0, 0, 0, 28, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101,115, 0, 3, 0, 0, 0, 28, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 40,102,111,114, 32,105,110,100,101,120,
+ 41, 0, 6, 0, 0, 0, 19, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 40,102,
+111,114, 32,108,105,109,105,116, 41, 0, 6, 0, 0, 0, 19, 0, 0, 0, 11, 0,
+ 0, 0, 0, 0, 0, 0, 40,102,111,114, 32,115,116,101,112, 41, 0, 6, 0, 0,
+ 0, 19, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,105, 0, 7, 0, 0, 0, 18,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 48,
+ 1, 0, 0, 0, 1, 0, 6, 14, 0, 0, 0, 69, 0, 0, 0, 70, 64,192, 0,134,
+128, 64, 0,195, 0, 0, 2, 69, 1, 0, 0, 70,193,192, 2, 92,128,128, 2,133,
+ 0, 0, 0,134, 0, 65, 1,192, 0, 0, 0, 0, 1,128, 0,156, 64,128, 1, 94,
+ 0, 0, 1, 30, 0,128, 0, 5, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,
+105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 82, 71, 66, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 77,101,114,103,101, 67,111,109,112,111,110,101,110,
+116,115, 0, 0, 0, 0, 0, 14, 0, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45,
+ 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 46,
+ 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 47,
+ 1, 0, 0, 48, 1, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0, 0, 0, 0, 13, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0,
+ 7, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,144, 1, 0, 0, 25, 0, 0, 0,
+ 50, 0, 0, 0, 73, 0, 0, 0, 97, 0, 0, 0,122, 0, 0, 0,130, 0, 0, 0,
+132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,
+132, 0, 0, 0,133, 0, 0, 0,133, 0, 0, 0,133, 0, 0, 0,134, 0, 0, 0,
+134, 0, 0, 0,134, 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,
+136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,
+136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0,
+137, 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,
+138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,
+139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,
+141, 0, 0, 0,144, 0, 0, 0,141, 0, 0, 0,146, 0, 0, 0,149, 0, 0, 0,
+146, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,152, 0, 0, 0,
+151, 0, 0, 0,154, 0, 0, 0,160, 0, 0, 0,154, 0, 0, 0,162, 0, 0, 0,
+162, 0, 0, 0,162, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0,164, 0, 0, 0,
+172, 0, 0, 0,176, 0, 0, 0,172, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,
+178, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,
+179, 0, 0, 0,180, 0, 0, 0,180, 0, 0, 0,180, 0, 0, 0,181, 0, 0, 0,
+181, 0, 0, 0,181, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,
+183, 0, 0, 0,183, 0, 0, 0,183, 0, 0, 0,184, 0, 0, 0,184, 0, 0, 0,
+184, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,
+186, 0, 0, 0,186, 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,
+188, 0, 0, 0,188, 0, 0, 0,188, 0, 0, 0,189, 0, 0, 0,189, 0, 0, 0,
+189, 0, 0, 0,190, 0, 0, 0,190, 0, 0, 0,190, 0, 0, 0,191, 0, 0, 0,
+191, 0, 0, 0,191, 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,
+193, 0, 0, 0,193, 0, 0, 0,193, 0, 0, 0,194, 0, 0, 0,194, 0, 0, 0,
+194, 0, 0, 0,195, 0, 0, 0,195, 0, 0, 0,195, 0, 0, 0,196, 0, 0, 0,
+196, 0, 0, 0,196, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,
+198, 0, 0, 0,198, 0, 0, 0,198, 0, 0, 0,199, 0, 0, 0,199, 0, 0, 0,
+199, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,201, 0, 0, 0,
+201, 0, 0, 0,201, 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,
+203, 0, 0, 0,203, 0, 0, 0,203, 0, 0, 0,204, 0, 0, 0,204, 0, 0, 0,
+204, 0, 0, 0,205, 0, 0, 0,205, 0, 0, 0,205, 0, 0, 0,206, 0, 0, 0,
+206, 0, 0, 0,206, 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,
+208, 0, 0, 0,208, 0, 0, 0,208, 0, 0, 0,209, 0, 0, 0,209, 0, 0, 0,
+209, 0, 0, 0,210, 0, 0, 0,210, 0, 0, 0,210, 0, 0, 0,211, 0, 0, 0,
+211, 0, 0, 0,211, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,
+212, 0, 0, 0,212, 0, 0, 0,214, 0, 0, 0,227, 0, 0, 0,214, 0, 0, 0,
+235, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,
+237, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,
+238, 0, 0, 0,239, 0, 0, 0,239, 0, 0, 0,239, 0, 0, 0,240, 0, 0, 0,
+240, 0, 0, 0,240, 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,
+242, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,243, 0, 0, 0,243, 0, 0, 0,
+243, 0, 0, 0,244, 0, 0, 0,244, 0, 0, 0,244, 0, 0, 0,245, 0, 0, 0,
+245, 0, 0, 0,245, 0, 0, 0,246, 0, 0, 0,246, 0, 0, 0,246, 0, 0, 0,
+247, 0, 0, 0,247, 0, 0, 0,247, 0, 0, 0,248, 0, 0, 0,248, 0, 0, 0,
+248, 0, 0, 0,250, 0, 0, 0,254, 0, 0, 0,250, 0, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
+ 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0,
+ 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 5, 1, 0, 0,
+ 9, 1, 0, 0, 5, 1, 0, 0, 11, 1, 0, 0, 15, 1, 0, 0, 11, 1, 0, 0,
+ 17, 1, 0, 0, 17, 1, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 18, 1, 0, 0,
+ 18, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0,
+ 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 20, 1, 0, 0, 20, 1, 0, 0,
+ 20, 1, 0, 0, 21, 1, 0, 0, 21, 1, 0, 0, 21, 1, 0, 0, 22, 1, 0, 0,
+ 22, 1, 0, 0, 22, 1, 0, 0, 24, 1, 0, 0, 29, 1, 0, 0, 24, 1, 0, 0,
+ 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0,
+ 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0,
+ 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0,
+ 32, 1, 0, 0, 34, 1, 0, 0, 42, 1, 0, 0, 34, 1, 0, 0, 44, 1, 0, 0,
+ 48, 1, 0, 0, 44, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0,
+ 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 51, 1, 0, 0, 51, 1, 0, 0,
+ 51, 1, 0, 0, 52, 1, 0, 0, 52, 1, 0, 0, 52, 1, 0, 0, 53, 1, 0, 0,
+ 53, 1, 0, 0, 53, 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0,
+ 55, 1, 0, 0, 55, 1, 0, 0, 55, 1, 0, 0, 56, 1, 0, 0, 56, 1, 0, 0,
+ 56, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0,
+ 57, 1, 0, 0, 57, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0,
+ 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0,
+ 59, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0,
+ 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0,
+ 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0,
+ 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0,
+ 62, 1, 0, 0, 62, 1, 0, 0, 63, 1, 0, 0, 63, 1, 0, 0, 63, 1, 0, 0,
+ 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0,
+ 64, 1, 0, 0, 64, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0,
+ 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 66, 1, 0, 0,
+ 66, 1, 0, 0, 66, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0,
+ 68, 1, 0, 0, 68, 1, 0, 0, 68, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0,
+ 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0,
+ 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0,
+ 70, 1, 0, 0, 70, 1, 0, 0, 71, 1, 0, 0, 71, 1, 0, 0, 71, 1, 0, 0,
+ 72, 1, 0, 0, 72, 1, 0, 0, 72, 1, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101, 79,110,101,
+ 68,101,115,116, 0, 1, 0, 0, 0,143, 1, 0, 0, 18, 0, 0, 0, 0, 0, 0,
+ 0, 84,119,111, 83,111,117,114, 99,101,115, 79,110,101, 68,101,115,116, 0, 2,
+ 0, 0, 0,143, 1, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 84,104,114,101,101,
+ 83,111,117,114, 99,101,115, 79,110,101, 68,101,115,116, 0, 3, 0, 0, 0,143,
+ 1, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101,
+ 84,119,111, 68,101,115,116,115, 0, 4, 0, 0, 0,143, 1, 0, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101, 84,104,114,101,101, 68,
+101,115,116,115, 0, 5, 0, 0, 0,143, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0,
+ 0,104,111,117,103,104, 95,104,101,105,103,104,116, 0, 6, 0, 0, 0,143, 1,
+ 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,105,110,116, 95,100, 97,116, 97,116,121,
+112,101, 0,182, 0, 0, 0,143, 1, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_process51/im_process_be64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_process_le64.loh b/im/src/lua5/loh/im_process_le64.loh
new file mode 100755
index 0000000..fc76f99
--- /dev/null
+++ b/im/src/lua5/loh/im_process_le64.loh
@@ -0,0 +1,897 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_process51/im_process_le64.lo")==0) lua_call(L, 0, 0);
+*/
+/* ../obj/imlua_process51/im_process_le64.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,112,114,111, 99,101,115,115, 46,108,117, 97,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13,144, 1, 0, 0, 36, 0, 0,
+ 0,100, 64, 0, 0,164,128, 0, 0,228,192, 0, 0, 36, 1, 1, 0,100, 65, 1,
+ 0,128, 1, 0, 0,193, 1, 0, 0, 3, 2, 0, 5,197, 66, 0, 0,198,130,192,
+ 5,156, 65, 0, 3,128, 1, 0, 0,193,193, 0, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 1, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 1, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 1, 0, 1,194, 1, 0, 64, 2,128, 2,133, 66, 0,
+ 0,134, 2, 66, 5,197, 66, 0, 0,198, 66,194, 5,156, 65, 0, 3,128, 1, 0,
+ 0,193,129, 2, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 2, 0, 3, 2, 0,
+ 5,197, 66, 0, 0,198, 2,195, 5,156, 65, 0, 3,128, 1, 0, 0,193, 65, 3,
+ 0, 3, 2,128, 4,133, 66, 0, 0,134,130, 67, 5,195, 2,128, 5,156, 65, 0,
+ 3,133, 65, 0, 0,228,129, 1, 0,137,193,129,135,133, 65, 0, 0,228,193, 1,
+ 0,137,193, 1,136,128, 1, 0, 0,193, 65, 4, 0, 36, 2, 2, 0,100, 66, 2,
+ 0,156, 65, 0, 2,133, 65, 0, 0,228,129, 2, 0,137,193, 1,137,128, 1,128,
+ 0,193,193, 4, 0,156, 65, 0, 1,133, 65, 0, 0,228,193, 2, 0,137,193, 1,
+138,133, 65, 0, 0,228, 1, 3, 0,137,193,129,138,128, 1, 0, 0,193,129, 5,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 5, 0, 36, 66, 3, 0,100,130, 3,
+ 0,156, 65, 0, 2,128, 1, 0, 0,193, 1, 6, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 65, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 6, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 7,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 7, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 7, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 7, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 1, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 8,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 8, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 9, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 65, 9, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 9,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 9, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 10, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 10, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 10, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 10,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 11, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 65, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 11, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 12,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 12, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 12, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 12, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 1, 13, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 13,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 13, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 13, 0,156, 65, 0, 1,128, 1,128, 1,193, 1, 14, 0, 3, 2, 0,
+ 4,100,194, 3, 0,156, 65, 0, 2,133, 65, 0, 0,228, 1, 4, 0,137,193,129,
+156,164, 65, 4, 0,192, 1, 0, 0, 1,130, 14, 0, 67, 2,128, 5, 0, 3, 0,
+ 3,220, 65, 0, 3,192, 1, 0, 0, 1,194, 14, 0, 67, 2,128, 5, 0, 3, 0,
+ 3,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 15, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 66, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 15, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,194, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 16,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 16, 0,220, 65, 0, 1,192, 1,128,
+ 0, 1,130, 16, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 16, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 2, 17, 0,220, 65, 0, 1,192, 1,128, 0, 1, 66, 17,
+ 0,220, 65, 0, 1,197, 65, 0, 0, 36,130, 4, 0,201, 1, 2,163,192, 1,128,
+ 0, 1,194, 17, 0,220, 65, 0, 1,192, 1, 0, 1, 1, 2, 18, 0,220, 65, 0,
+ 1,192, 1,128, 1, 1, 66, 18, 0,220, 65, 0, 1,192, 1,128, 0, 1,130, 18,
+ 0, 67, 2,128, 5, 5, 67, 0, 0, 6,195, 82, 6,220, 65, 0, 3,197, 65, 0,
+ 0, 36,194, 4, 0,201, 1, 2,166,197, 65, 0, 0, 36, 2, 5, 0,201, 1,130,
+166,192, 1,128, 0, 1,130, 19, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 19,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 20, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198, 66,212, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,130, 20,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 20, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 2, 21, 0,220, 65, 0, 1,197, 65, 0, 0, 36, 66, 5, 0,201, 1,130,
+170,192, 1, 0, 2, 1,130, 21, 0, 67, 2, 0, 5,197, 66, 0, 0,198, 2,194,
+ 5, 5, 67, 0, 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0, 1, 1,194, 21,
+ 0, 67, 2, 0, 5,197, 66, 0, 0,198, 2,214, 5, 5, 67, 0, 0, 6, 67, 86,
+ 6,220, 65, 0, 3,197, 65, 0, 0, 36,130, 5, 0,201, 1, 2,173,197, 65, 0,
+ 0, 36,194, 5, 0,201, 1,130,173,192, 1, 0, 0, 1, 2, 23, 0, 67, 2,128,
+ 5, 5, 67, 0, 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 23,
+ 0,220, 65, 0, 1,192, 1,128, 0, 1,130, 23, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1,194, 23, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 24, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 66, 24, 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 24,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 24, 0, 67, 2,128, 5, 5, 67, 0,
+ 0, 6, 67, 86, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 25, 0, 67, 2,128,
+ 5, 5, 67, 0, 0, 6, 67, 86, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 25,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 25, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,194, 25,
+ 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0,
+ 3,192, 1, 0, 0, 1, 2, 26, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1,128, 0, 1, 66, 26, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,130, 26, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,194, 26, 0, 67, 2, 0,
+ 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1, 2, 27, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 27, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,130, 27, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 27,
+ 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0,
+ 3,192, 1, 0, 0, 1, 2, 28, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195,
+ 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 28, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,130, 28, 0,220, 65, 0, 1, 30, 0,128, 0,115, 0, 0,
+ 0, 4, 19, 0, 0, 0, 0, 0, 0, 0, 65,110, 97,108,121,122,101, 70,105,110,
+100, 82,101,103,105,111,110,115, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 85, 83, 72, 79, 82, 84, 0, 4, 21, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114,105,109,101,116,
+101,114, 76,105,110,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 82,101,109,111,118,101, 66,121, 65,114,101, 97, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 70,105,108,108, 72,111,108,101,
+115, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 72,111,
+117,103,104, 76,105,110,101,115, 0, 3, 0, 0, 0, 0, 0,128,102, 64, 4, 5,
+ 0, 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 73, 78, 84, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 72,111,117,103,104, 76,105,110,101,115, 68,114, 97,119, 0, 4, 25, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 68,105,115,116, 97,110, 99,101,
+ 84,114, 97,110,115,102,111,114,109, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 70,
+ 76, 79, 65, 84, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,101,103,105,111,110, 97,108, 77, 97,120,105,109,117,109, 0, 4, 7, 0,
+ 0, 0, 0, 0, 0, 0, 66, 73, 78, 65, 82, 89, 0, 4, 17, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 82,101,100,117, 99,101, 78,101,119, 0, 4,
+ 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,115,105,122,
+101, 78,101,119, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,101,100,117, 99,101, 66,121, 52, 0, 4, 15, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 67,114,111,112, 78,101,119, 0, 4, 14, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,115,101,114,116, 0, 4, 21,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,100,100, 77, 97,114,
+103,105,110,115, 78,101,119, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 82,111,116, 97,116,101, 78,101,119, 0, 4, 17, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,116, 97,116,101, 82,101,102, 0,
+ 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,116, 97,
+116,101, 57, 48, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,111,116, 97,116,101, 49, 56, 48, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 77,105,114,114,111,114, 0, 4, 12, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 70,108,105,112, 0, 4, 14, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,100,105, 97,108, 0, 4, 25,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,
+114,112,104, 67,111,110,118,111,108,118,101, 0, 4, 22, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 69,114,111,
+100,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,
+114, 97,121, 77,111,114,112,104, 68,105,108, 97,116,101, 0, 4, 21, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104,
+ 79,112,101,110, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 71,114, 97,121, 77,111,114,112,104, 67,108,111,115,101, 0, 4, 23, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,
+104, 84,111,112, 72, 97,116, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 87,101,108,108, 0, 4, 25,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,
+114,112,104, 71,114, 97,100,105,101,110,116, 0, 4, 24, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,111,110,118,
+111,108,118,101, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 66,105,110, 77,111,114,112,104, 69,114,111,100,101, 0, 4, 22, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 68,
+105,108, 97,116,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 66,105,110, 77,111,114,112,104, 79,112,101,110, 0, 4, 21, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,
+108,111,115,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 66,105,110, 77,111,114,112,104, 79,117,116,108,105,110,101, 0, 4, 20, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,
+104, 84,104,105,110, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 77,101,100,105, 97,110, 67,111,110,118,111,108,118,101, 0, 4, 21, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,111,
+110,118,111,108,118,101, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 82, 97,110,107, 67,108,111,115,101,115,116, 67,111,110,118,111,108,
+118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,
+ 97,110,107, 77, 97,120, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,107, 77,105,110, 67,111,
+110,118,111,108,118,101, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 67,111,110,118,111,108,118,101, 0, 4, 19, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,101, 83,101,112, 0,
+ 4, 19, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,110,118,
+111,108,118,101, 82,101,112, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 67,111,110,118,111,108,118,101, 68,117, 97,108, 0, 4, 23, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,109,112, 97,115,115,
+ 67,111,110,118,111,108,118,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 77,101, 97,110, 67,111,110,118,111,108,118,101, 0, 4, 24,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71, 97,117,115,115,105,
+ 97,110, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 66, 97,114,108,101,116,116, 67,111,110,118,111,108,
+118,101, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,
+110,116,101,114,108, 97, 99,101, 83,112,108,105,116, 0, 4, 25, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,116,101,114,108, 97, 99,101, 83,
+112,108,105,116, 78,101,119, 0, 4, 30, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 68,105,102,102, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,
+110,118,111,108,118,101, 0, 4, 29, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 76, 97,112, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,110,118,
+111,108,118,101, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 83,111, 98,101,108, 67,111,110,118,111,108,118,101, 0, 4, 26, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,110,101, 69,100,103,
+101, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 80,114,101,119,105,116,116, 67,111,110,118,111,108,118,
+101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 90,101,
+114,111, 67,114,111,115,115,105,110,103, 0, 4, 13, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 67, 97,110,110,121, 0, 4, 22, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 85,110, 65,114,105,116,104,109,101,116,105,
+ 99, 79,112, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 65,114,105,116,104,109,101,116,105, 99, 79,112, 0, 4, 15, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 85,110,115,104, 97,114,112, 0, 4, 13, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,104, 97,114,112, 0, 4,
+ 19, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,104, 97,114,112,
+ 75,101,114,110,101,108, 0, 4, 28, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 65,114,105,116,104,109,101,116,105, 99, 67,111,110,115,116, 79,112,
+ 78,101,119, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 66,108,101,110,100, 67,111,110,115,116, 0, 4, 13, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 66,108,101,110,100, 0, 4, 20, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,108,101,
+120, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,101,
+114,103,101, 67,111,109,112,108,101,120, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,
+ 67, 70, 76, 79, 65, 84, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 77,117,108,116,105,112,108,101, 77,101, 97,110, 78,101,119, 0, 4,
+ 25, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,117,108,116,105,
+112,108,101, 83,116,100, 68,101,118, 78,101,119, 0, 4, 22, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 65,117,116,111, 67,111,118, 97,114,105, 97,
+110, 99,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 77,117,108,116,105,112,108,121, 67,111,110,106, 0, 4, 26, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 81,117, 97,110,116,105,122,101, 82, 71, 66,
+ 85,110,105,102,111,114,109, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 77, 65, 80,
+ 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 81,117, 97,
+110,116,105,122,101, 71,114, 97,121, 85,110,105,102,111,114,109, 0, 4, 23, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 69,120,112, 97,110,100, 72,
+105,115,116,111,103,114, 97,109, 0, 4, 25, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 69,113,117, 97,108,105,122,101, 72,105,115,116,111,103,114,
+ 97,109, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,
+112,108,105,116, 89, 67,104,114,111,109, 97, 78,101,119, 0, 4, 16, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 72, 83, 73, 0,
+ 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,101,114,103,
+101, 72, 83, 73, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 82, 71, 66, 0, 4, 5,
+ 0, 0, 0, 0, 0, 0, 0, 66, 89, 84, 69, 0, 4, 26, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,111,110,101,
+110,116,115, 78,101,119, 0, 4, 26, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 77,101,114,103,101, 67,111,109,112,111,110,101,110,116,115, 78,101,
+119, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 78,111,
+114,109, 97,108,105,122,101, 67,111,109,112,111,110,101,110,116,115, 0, 4, 20,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,112,108, 97, 99,
+101, 67,111,108,111,114, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 66,105,116,119,105,115,101, 79,112, 0, 4, 18, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 66,105,116,119,105,115,101, 78,111,116, 0,
+ 4, 15, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,116, 77,
+ 97,115,107, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 66,105,116, 80,108, 97,110,101, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 84,111,110,101, 71, 97,109,117,116, 0, 4, 19, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 85,110, 78,111,114,109, 97,108,105,
+122,101, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 68,
+105,114,101, 99,116, 67,111,110,118, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 78,101,103, 97,116,105,118,101, 0, 4, 30, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,111,110,116,
+114, 97,115,116, 84,104,114,101,115,104,111,108,100, 0, 4, 25, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 76,111, 99, 97,108, 77, 97,120, 84,104,
+114,101,115,104,111,108,100, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 84,104,114,101,115,104,111,108,100, 0, 4, 23, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 84,104,114,101,115,104,111,108,100, 66,
+121, 68,105,102,102, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 72,121,115,116,101,114,101,115,105,115, 84,104,114,101,115,104,111,108,
+100, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 85,110,
+105,102,111,114,109, 69,114,114, 84,104,114,101,115,104,111,108,100, 0, 4, 28,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 68,105,102,117,115,105,
+111,110, 69,114,114, 84,104,114,101,115,104,111,108,100, 0, 4, 24, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114, 99,101,110,116, 84,104,
+114,101,115,104,111,108,100, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 79,116,115,117, 84,104,114,101,115,104,111,108,100, 0, 4, 23,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,105,110, 77, 97,120,
+ 84,104,114,101,115,104,111,108,100, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 83,108,105, 99,101, 84,104,114,101,115,104,111,108,100,
+ 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,105,120,
+101,108, 97,116,101, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 80,111,115,116,101,114,105,122,101, 0, 24, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 25, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0,
+ 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,
+133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0,
+ 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,
+137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0,
+ 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0,
+ 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 5, 1, 7, 8, 23, 0, 0,
+ 0,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128,
+ 0,132, 1, 0, 1,196, 1,128, 1,156,128, 0, 3,196, 0, 0, 2, 0, 1, 0,
+ 0, 64, 1, 0, 1,133,129, 0, 0,192, 1,128, 0,156, 1, 0, 1,220,128, 0,
+ 0,218, 0, 0, 0, 22,192, 0,128, 0, 1,128, 1, 64, 1, 0, 1, 30, 1,128,
+ 1, 22, 0, 0,128,158, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0,
+ 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109,
+ 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,
+ 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 23, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15,
+ 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18,
+ 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 19,
+ 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20,
+ 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 22, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 22, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8,
+ 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 15,
+ 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,
+105,100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0,
+ 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 9, 0, 0, 0, 9,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24,
+ 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 25,
+ 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110,
+ 97,109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+119,105,100,116,104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0,
+ 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,
+112,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,
+117,110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 31, 0, 0, 0, 50, 0, 0, 0, 0, 5, 0, 11, 22, 0, 0, 0,
+ 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2, 5,130, 0, 0,
+ 6,194, 64, 4, 65, 2, 1, 0,128, 2, 0, 0, 28, 2,128, 1,156, 65, 0, 0,
+133, 1, 0, 0,192, 1, 0, 0, 1, 66, 1, 0,213, 1,130, 3, 36, 2, 0, 0,
+ 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,
+137, 1,130, 3, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0,
+ 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0,115,116,114,105,110,103, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0,102,111,114,109, 97,116, 0, 4, 24, 0, 0, 0, 0, 0, 0,
+ 0,117,110,100,101,102,105,110,101,100, 32,102,117,110, 99,116,105,111,110, 32,
+ 96, 37,115, 39, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 5, 2,
+ 7, 10, 24, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1,
+ 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1,
+ 0, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 5,130, 0, 0, 64, 2,
+ 0, 1, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22,192, 0,128, 64, 1,
+ 0, 2,128, 1,128, 1, 94, 1,128, 1, 22, 0, 0,128,222, 0, 0, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17,
+ 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,
+115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0,
+ 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0,
+ 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0,
+ 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0,
+ 49, 0, 0, 0, 5, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,
+105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 23, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0,
+ 8, 0, 0, 0, 23, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0,
+ 16, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+119,105,100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 22, 0, 0, 0, 32, 0, 0, 0,
+ 32, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,
+ 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 0,
+ 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0,
+ 50, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,
+110, 97,109,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+ 0,119,105,100,116,104, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 21, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0,
+ 0, 0, 21, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,
+121,112,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+102,117,110, 99, 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 56, 0, 0, 0, 73, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0,
+ 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0,
+ 1,133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0,
+ 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128,
+ 2,137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0,
+ 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116,
+ 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 72, 0, 0, 0, 5, 3, 7, 12, 25, 0,
+ 0, 0, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0, 0,196, 1,
+128, 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0, 2,128, 1,
+ 0, 0,192, 1,128, 0, 0, 2, 0, 1, 64, 2, 0, 2,133,130, 0, 0,192, 2,
+128, 1,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22,192, 0,128,128, 1,
+128, 2,192, 1, 0, 2,158, 1,128, 1, 22, 0, 0,128, 30, 1, 0, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17,
+ 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,
+115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
+ 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
+ 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0,
+ 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0,
+ 67, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0,
+ 70, 0, 0, 0, 72, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,
+115,114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 24, 0, 0, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0,
+ 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109,
+ 97,103,101, 51, 0, 0, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 97,114,103, 0, 0, 0, 0, 0, 24, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 24, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 17, 0, 0, 0, 24, 0, 0, 0, 5,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,
+110, 99, 0, 17, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 58, 0, 0, 0, 58,
+ 0, 0, 0, 58, 0, 0, 0, 61, 0, 0, 0, 61, 0, 0, 0, 61, 0, 0, 0, 61,
+ 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72,
+ 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 73, 0, 0, 0, 6, 0, 0, 0, 9,
+ 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,
+111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0,
+ 97, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,
+133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0,
+ 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1,
+ 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0,
+ 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0,
+ 0, 96, 0, 0, 0, 5, 1, 7, 10, 35, 0, 0, 0,133, 0, 0, 0,134, 64, 64,
+ 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0, 1,196, 1,128,
+ 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 68, 1, 0,
+ 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3, 4, 1, 0,
+ 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1, 5,130, 0, 0, 64, 2,128,
+ 0, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22, 0, 1,128, 64, 1, 0,
+ 2,128, 1, 0, 1,192, 1,128, 1, 94, 1, 0, 2, 22,128, 0,128, 64, 1, 0,
+ 1,128, 1,128, 1, 94, 1,128, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0,
+ 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109,
+ 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0,
+ 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 35, 0, 0, 0, 86,
+ 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86,
+ 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87,
+ 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87,
+ 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90,
+ 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 91,
+ 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92,
+ 0, 0, 0, 94, 0, 0, 0, 94, 0, 0, 0, 94, 0, 0, 0, 96, 0, 0, 0, 5,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103,
+ 0, 0, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116,
+ 95,105,109, 97,103,101, 49, 0, 8, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0,
+ 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 50, 0, 16, 0, 0, 0, 34,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 24, 0, 0, 0, 34,
+ 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104,
+ 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0,
+ 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 81,
+ 0, 0, 0, 81, 0, 0, 0, 81, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84,
+ 0, 0, 0, 84, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96,
+ 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 97, 0, 0, 0, 6,
+ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,
+104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,
+105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0,
+ 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0,
+ 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+103, 0, 0, 0,122, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0,
+ 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,
+192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0,
+ 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3,
+ 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0,
+ 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,108, 0, 0, 0,121, 0, 0, 0, 5, 1, 7, 12, 46, 0, 0, 0,133, 0, 0,
+ 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0,
+ 1,196, 1,128, 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0,
+ 0, 68, 1, 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0,
+ 3, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0, 0,196, 1,128,
+ 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0, 2,128, 1, 0,
+ 0,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,133,130, 0, 0,192, 2,128,
+ 0,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22, 64, 1,128,128, 1,128,
+ 2,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,158, 1,128, 2, 22,192, 0,
+128,128, 1, 0, 1,192, 1,128, 1, 0, 2, 0, 2,158, 1, 0, 2, 30, 0,128,
+ 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0,
+ 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,
+101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 46, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110,
+ 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,111,
+ 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111,
+ 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112,
+ 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112,
+ 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115,
+ 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,116,
+ 0, 0, 0,116, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117,
+ 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,119, 0, 0, 0,119, 0, 0, 0,119,
+ 0, 0, 0,119, 0, 0, 0,121, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 45, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 45, 0, 0,
+ 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 49, 0,
+ 8, 0, 0, 0, 45, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,
+105,109, 97,103,101, 50, 0, 16, 0, 0, 0, 45, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 51, 0, 24, 0, 0, 0, 45, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 33, 0, 0, 0, 45, 0,
+ 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0,
+ 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0,102,117,110, 99, 0, 17, 0, 0, 0,104, 0, 0, 0,104, 0, 0, 0,105, 0,
+ 0, 0,105, 0, 0, 0,105, 0, 0, 0,108, 0, 0, 0,108, 0, 0, 0,108, 0,
+ 0, 0,108, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0,
+ 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,122, 0, 0, 0, 6, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,
+103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2,
+ 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126,
+ 0, 0, 0,130, 0, 0, 0, 0, 1, 0, 7, 18, 0, 0, 0,100, 0, 0, 0,133,
+ 0, 0, 0,134, 64, 64, 1,192, 0,128, 0, 11,129, 64, 0, 28, 1, 0, 1,220,
+128, 0, 0, 0, 1,128, 0, 75,193, 64, 0, 92, 1, 0, 1, 28,129, 0, 0,204,
+ 0,129, 1,156,128, 0, 1,143, 0, 65, 1,206,128, 0,130,204, 64,193, 1,222,
+ 0, 0, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,
+109, 97,116,104, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,115,113,114,116, 0, 4,
+ 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 3,
+ 0, 0, 0, 0, 0, 0,240, 63, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+127, 0, 0, 0,127, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 78, 0, 0, 0,
+ 94, 0, 0, 1, 30, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+127, 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0,120, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 18, 0,
+ 0, 0,127, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0,
+ 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0,
+ 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,129, 0,
+ 0, 0,129, 0, 0, 0,129, 0, 0, 0,130, 0, 0, 0, 3, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 17, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0,115,113,114, 0, 1, 0, 0, 0, 17, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 0, 0,114,109, 97,120, 0, 14, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,141, 0, 0, 0,144, 0, 0,
+ 0, 0, 3, 0, 7, 14, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0,
+ 0, 64, 1,128, 0,128, 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0, 6,129, 64,
+ 2, 64, 1, 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30, 1,128,
+ 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 82,101,100,117, 99,101, 0, 0, 0, 0, 0, 14, 0, 0, 0,142, 0,
+ 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0,
+ 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0,
+ 0, 0,143, 0, 0, 0,143, 0, 0, 0,144, 0, 0, 0, 4, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0,
+ 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116,
+ 95,105,109, 97,103,101, 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,146, 0, 0, 0,149, 0, 0, 0, 0, 3, 0, 7, 14,
+ 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 64, 1,128, 0,128,
+ 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0, 6,129, 64, 2, 64, 1, 0, 0,128,
+ 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,128, 0, 3,
+ 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0,
+ 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100,
+ 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,115,
+105,122,101, 0, 0, 0, 0, 0, 14, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,
+147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,148, 0, 0, 0,
+148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,
+148, 0, 0, 0,149, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 13, 0, 0, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 13,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101,
+ 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,151, 0, 0, 0,151, 0, 0, 0, 0, 1, 0, 3, 5, 0, 0, 0, 75, 0, 64,
+ 0, 92,128, 0, 1, 79, 64,192, 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0,
+ 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 64, 0, 0, 0, 0, 5, 0, 0, 0,151, 0, 0, 0,151, 0, 0,
+ 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0, 0,
+ 1, 0, 3, 5, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1, 79, 64,192, 0, 94,
+ 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,
+ 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0,
+ 5, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,
+152, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,
+101, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,154, 0, 0, 0,160, 0, 0, 0, 0, 5, 0, 13, 19, 0, 0, 0, 77, 65,
+ 0, 1, 76, 1,192, 2,141,193, 0, 2,140, 1, 64, 3,197, 65, 0, 0,198,129,
+192, 3, 0, 2, 0, 0, 64, 2,128, 2,128, 2, 0, 3,220,129, 0, 2, 5, 66,
+ 0, 0, 6,194, 64, 4, 64, 2, 0, 0,128, 2,128, 3,192, 2,128, 0, 0, 3,
+128, 1, 28, 66,128, 2,222, 1, 0, 1, 30, 0,128, 0, 4, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4,
+ 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66,
+ 97,115,101,100, 0, 4, 12, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 67,114,111,112, 0, 0, 0, 0, 0, 19, 0, 0, 0,155, 0, 0, 0,155, 0,
+ 0, 0,156, 0, 0, 0,156, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0,
+ 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0,158, 0,
+ 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0,
+ 0, 0,159, 0, 0, 0,160, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 18, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 0, 0,120,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0,120,109, 97,120, 0, 0, 0, 0, 0, 18, 0,
+ 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,121,109,105,110, 0, 0, 0, 0, 0, 18,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,121,109, 97,120, 0, 0, 0, 0, 0,
+ 18, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 2, 0,
+ 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116,
+ 0, 4, 0, 0, 0, 18, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116,
+ 95,105,109, 97,103,101, 0, 10, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0, 0, 5, 0, 13, 19,
+ 0, 0, 0, 77, 65, 0, 1, 76, 1,192, 2,141,193, 0, 2,140, 1, 64, 3,197,
+ 65, 0, 0,198,129,192, 3, 0, 2, 0, 0, 64, 2,128, 2,128, 2, 0, 3,220,
+129, 0, 2, 5, 66, 0, 0, 6,194, 64, 4, 64, 2, 0, 0,128, 2,128, 3,192,
+ 2,128, 0, 0, 3,128, 1, 28, 66,128, 2,222, 1, 0, 1, 30, 0,128, 0, 4,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0, 0, 0, 0, 0,
+ 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,
+101, 97,116,101, 66, 97,115,101,100, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 65,100,100, 77, 97,114,103,105,110,115, 0, 0, 0, 0,
+ 0, 19, 0, 0, 0,165, 0, 0, 0,165, 0, 0, 0,166, 0, 0, 0,166, 0, 0,
+ 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0,
+ 0,167, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0,
+ 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,170, 0, 0,
+ 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,
+103,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,120,
+109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+120,109, 97,120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0,121,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0,121,109, 97,120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0,119,105,100,116,104, 0, 2, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 4, 0, 0, 0, 18, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 10, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0,
+ 0, 0,176, 0, 0, 0, 0, 4, 0, 13, 26, 0, 0, 0, 5, 1, 0, 0, 6, 65,
+ 64, 2, 75,129, 64, 0, 92,129, 0, 1,139,193, 64, 0,156,129, 0, 1,192, 1,
+128, 0, 0, 2, 0, 1, 28,193,128, 2,133, 1, 0, 0,134, 1, 65, 3,192, 1,
+ 0, 0, 0, 2, 0, 2, 64, 2,128, 2,156,129, 0, 2,197, 1, 0, 0,198, 65,
+193, 3, 0, 2, 0, 0, 64, 2, 0, 3,128, 2,128, 0,192, 2, 0, 1, 0, 3,
+128, 1,220,129, 0, 3, 0, 2, 0, 3,222, 1,128, 1, 30, 0,128, 0, 6, 0,
+ 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 22, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 67, 97,108, 99, 82,111,116, 97,116,101,
+ 83,105,122,101, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,
+100, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,
+116, 97,116,101, 0, 0, 0, 0, 0, 26, 0, 0, 0,173, 0, 0, 0,173, 0, 0,
+ 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0,
+ 0,173, 0, 0, 0,173, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0,
+ 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0,175, 0, 0,
+ 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0,
+ 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,176, 0, 0, 0, 7, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0,
+ 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 99,111,115, 48, 0,
+ 0, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,115,105,110, 48,
+ 0, 0, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,111,114,100,
+101,114, 0, 0, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,
+105,100,116,104, 0, 9, 0, 0, 0, 25, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+ 0,104,101,105,103,104,116, 0, 9, 0, 0, 0, 25, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 15, 0, 0, 0, 25, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0, 0, 1, 0, 3, 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0, 1, 94, 0,
+ 0, 0, 30, 0,128, 0, 1, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,
+101,105,103,104,116, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0,179, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0, 0, 1, 0, 3,
+ 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0, 1, 94, 0, 0, 0, 30, 0,128, 0,
+ 1, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179,
+ 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101,
+ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,212, 0, 0, 0,212, 0, 0, 0, 0, 1, 0, 3, 13, 0, 0, 0, 75, 0, 64,
+ 0, 92,128, 0, 1, 90, 0, 0, 0, 22,192, 0,128, 75, 0, 64, 0, 93, 0, 0,
+ 1, 94, 0, 0, 0, 22,192, 0,128, 75, 0, 64, 0, 92,128, 0, 1, 79, 64,192,
+ 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0,
+ 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0,
+ 0, 0, 13, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0,
+ 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0,
+ 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0, 1, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214, 0, 0, 0,
+227, 0, 0, 0, 0, 1, 0, 8, 36, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1,
+ 79, 64,192, 0,133,128, 0, 0,134,192, 64, 1,203, 0, 64, 0,220,128, 0, 1,
+ 1, 65, 0, 0,156,128,128, 1,154, 0, 0, 0, 22, 0, 0,128, 76, 0,193, 0,
+133, 64, 1, 0,134,128, 65, 1,192, 0, 0, 0, 3, 1, 0, 2, 64, 1,128, 0,
+156,128, 0, 2,197, 64, 1, 0,198,128,193, 1, 0, 1, 0, 0, 67, 1,128, 2,
+139, 1, 64, 0,156,129, 0, 1,143, 65, 64, 3,220,128, 0, 2, 5, 65, 1, 0,
+ 6,193, 65, 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1, 28, 65, 0, 2,
+ 0, 1, 0, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,128, 0, 8, 0, 0, 0,
+ 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 64, 4, 5, 0, 0, 0, 0, 0, 0, 0,109, 97,116,104, 0, 4,
+ 4, 0, 0, 0, 0, 0, 0, 0,109,111,100, 0, 3, 0, 0, 0, 0, 0, 0,240,
+ 63, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0,
+ 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4,
+ 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,116,101,114,
+108, 97, 99,101, 83,112,108,105,116, 0, 0, 0, 0, 0, 36, 0, 0, 0,216, 0,
+ 0, 0,216, 0, 0, 0,216, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0,
+ 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0,
+ 0, 0,218, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0,
+ 0, 0,221, 0, 0, 0,221, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0,
+ 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0,
+ 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0,
+ 0, 0,225, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,227, 0,
+ 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+100,115,116, 95,104,101,105,103,104,116, 49, 0, 3, 0, 0, 0, 35, 0, 0, 0,
+ 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 49, 0, 18,
+ 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,
+109, 97,103,101, 50, 0, 26, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,229, 0, 0, 0,235, 0, 0, 0, 0, 1, 0, 3, 14, 0,
+ 0, 0, 75, 0, 64, 0, 92,128, 0, 1,133, 64, 0, 0,134,128, 64, 1, 87,128,
+128, 0, 22,192, 0,128,133, 64, 0, 0,134,192, 64, 1, 23,128,128, 0, 22, 64,
+ 0,128,133, 64, 0, 0, 70, 0, 65, 1, 94, 0, 0, 1, 30, 0,128, 0, 5, 0,
+ 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 68, 97,116, 97, 84,121,112,101, 0,
+ 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 5, 0, 0, 0, 0, 0, 0,
+ 0, 66, 89, 84, 69, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 85, 83, 72, 79, 82,
+ 84, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 73, 78, 84, 0, 0, 0, 0, 0, 14,
+ 0, 0, 0,230, 0, 0, 0,230, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231,
+ 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231,
+ 0, 0, 0,232, 0, 0, 0,232, 0, 0, 0,234, 0, 0, 0,235, 0, 0, 0, 2,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0,
+ 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,
+112,101, 0, 2, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,250, 0, 0, 0,254, 0, 0, 0, 0, 3, 0, 9, 13, 0, 0, 0,197,
+ 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0,220,128, 0, 1, 5, 1, 0, 0, 6,
+129, 64, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 0, 2, 0, 1, 28,
+ 65,128, 2,222, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 25, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 65,114,105,116,104,109,101,116,105, 99, 67,
+111,110,115,116, 79,112, 0, 0, 0, 0, 0, 13, 0, 0, 0,251, 0, 0, 0,251,
+ 0, 0, 0,251, 0, 0, 0,251, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252,
+ 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,252, 0, 0, 0,253,
+ 0, 0, 0,254, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 12, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,115,114, 99, 95, 99,111,110,115,116, 0, 0, 0, 0, 0, 12,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,111,112, 0, 0, 0, 0, 0, 12, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0,
+ 4, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 1, 0, 0, 9, 1, 0, 0, 0, 2, 0, 6, 11, 0, 0, 0,133, 0, 0, 0,
+134, 64, 64, 1,198,128, 64, 0,156,128, 0, 1,197, 0, 0, 0,198,192,192, 1,
+ 0, 1, 0, 0, 64, 1, 0, 1,220, 64,128, 1,158, 0, 0, 1, 30, 0,128, 0,
+ 4, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,
+100, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 20, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 77,117,108,116,105,112,108,101, 77,101, 97,110, 0,
+ 0, 0, 0, 0, 11, 0, 0, 0, 6, 1, 0, 0, 6, 1, 0, 0, 6, 1, 0, 0,
+ 6, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0, 7, 1, 0, 0,
+ 7, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0,
+ 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0,
+ 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0,
+ 0,100,115,116, 95,105,109, 97,103,101, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 1, 0, 0, 15, 1, 0, 0, 0,
+ 2, 0, 7, 12, 0, 0, 0,133, 0, 0, 0,134, 64, 64, 1,198,128, 64, 0,156,
+128, 0, 1,197, 0, 0, 0,198,192,192, 1, 0, 1, 0, 0, 64, 1,128, 0,128,
+ 1, 0, 1,220, 64, 0, 2,158, 0, 0, 1, 30, 0,128, 0, 4, 0, 0, 0, 4,
+ 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0,
+ 0, 0, 0, 0,240, 63, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 77,117,108,116,105,112,108,101, 83,116,100, 68,101,118, 0, 0, 0, 0,
+ 0, 12, 0, 0, 0, 12, 1, 0, 0, 12, 1, 0, 0, 12, 1, 0, 0, 12, 1, 0,
+ 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0, 0, 13, 1, 0,
+ 0, 13, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 3, 0, 0, 0, 15, 0, 0,
+ 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0,
+ 0, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,109,101, 97,110,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 4, 0, 0, 0, 11, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 29, 1, 0,
+ 0, 0, 1, 0, 8, 28, 0, 0, 0, 69, 0, 0, 0, 70, 64,192, 0,128, 0, 0,
+ 0,195, 0, 0, 2, 69, 1, 0, 0, 70,129,192, 2,133, 1, 0, 0,134,193, 64,
+ 3, 92,128, 0, 3,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 3, 1,128,
+ 2,133, 1, 0, 0,134, 1, 65, 3,197, 1, 0, 0,198,193,192, 3,156,128, 0,
+ 3,197, 0, 0, 0,198, 64,193, 1, 0, 1, 0, 0, 64, 1,128, 0,128, 1, 0,
+ 1,220, 64, 0, 2,192, 0,128, 0, 0, 1, 0, 1,222, 0,128, 1, 30, 0,128,
+ 0, 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0,
+ 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,
+101,100, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 5, 0,
+ 0, 0, 0, 0, 0, 0, 66, 89, 84, 69, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+ 82, 71, 66, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 83,112,108,105,116, 89, 67,104,114,111,109, 97, 0, 0, 0, 0, 0, 28, 0, 0,
+ 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0,
+ 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 26, 1, 0,
+ 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0,
+ 0, 26, 1, 0, 0, 26, 1, 0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0,
+ 0, 27, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0, 0, 27, 1, 0, 0, 28, 1, 0,
+ 0, 28, 1, 0, 0, 28, 1, 0, 0, 29, 1, 0, 0, 3, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 27,
+ 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,121, 95,105,109, 97,103,101, 0, 9,
+ 0, 0, 0, 27, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 99,104,114,111,109,
+ 97, 95,105,109, 97,103,101, 0, 18, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 34, 1, 0, 0, 42, 1, 0, 0, 0, 1, 0, 14,
+ 29, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1,138, 0, 0, 0,193, 64, 0, 0,
+ 0, 1,128, 0, 65, 65, 0, 0,224,128, 2,128,197,129, 0, 0,198,193,192, 3,
+ 0, 2, 0, 1, 69, 2, 1, 0, 70, 66,193, 4,128, 2, 0, 0,195, 2, 0, 6,
+ 69, 3, 1, 0, 70,131,193, 6, 92, 2,128, 2,220, 65, 0, 0,223,192,252,127,
+197, 0, 1, 0,198,192,193, 1, 0, 1, 0, 0, 64, 1, 0, 1,220, 64,128, 1,
+197, 0, 2, 0, 0, 1, 0, 1,221, 0, 0, 1,222, 0, 0, 0, 30, 0,128, 0,
+ 9, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 68,101,112,116,104, 0, 3,
+ 0, 0, 0, 0, 0, 0,240, 63, 4, 6, 0, 0, 0, 0, 0, 0, 0,116, 97, 98,
+108,101, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,105,110,115,101,114,116, 0, 4,
+ 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0,
+ 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 5, 0,
+ 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,111,110,101,110,
+116,115, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0,
+ 0, 0, 0, 29, 0, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 37,
+ 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 38, 1, 0, 0, 38,
+ 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38,
+ 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 37,
+ 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 40, 1, 0, 0, 40,
+ 1, 0, 0, 41, 1, 0, 0, 41, 1, 0, 0, 41, 1, 0, 0, 41, 1, 0, 0, 42,
+ 1, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+ 0,100,101,112,116,104, 0, 2, 0, 0, 0, 28, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,105,109, 97,103,101,115, 0, 3, 0, 0, 0, 28, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 40,102,111,114, 32,105,110,100,101,120,
+ 41, 0, 6, 0, 0, 0, 19, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 40,102,
+111,114, 32,108,105,109,105,116, 41, 0, 6, 0, 0, 0, 19, 0, 0, 0, 11, 0,
+ 0, 0, 0, 0, 0, 0, 40,102,111,114, 32,115,116,101,112, 41, 0, 6, 0, 0,
+ 0, 19, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,105, 0, 7, 0, 0, 0, 18,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 48,
+ 1, 0, 0, 0, 1, 0, 6, 14, 0, 0, 0, 69, 0, 0, 0, 70, 64,192, 0,134,
+128, 64, 0,195, 0, 0, 2, 69, 1, 0, 0, 70,193,192, 2, 92,128,128, 2,133,
+ 0, 0, 0,134, 0, 65, 1,192, 0, 0, 0, 0, 1,128, 0,156, 64,128, 1, 94,
+ 0, 0, 1, 30, 0,128, 0, 5, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,
+105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101,
+ 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 82, 71, 66, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 77,101,114,103,101, 67,111,109,112,111,110,101,110,
+116,115, 0, 0, 0, 0, 0, 14, 0, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45,
+ 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 45, 1, 0, 0, 46,
+ 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 46, 1, 0, 0, 47,
+ 1, 0, 0, 48, 1, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0, 0, 0, 0, 13, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0,
+ 7, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,144, 1, 0, 0, 25, 0, 0, 0,
+ 50, 0, 0, 0, 73, 0, 0, 0, 97, 0, 0, 0,122, 0, 0, 0,130, 0, 0, 0,
+132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,
+132, 0, 0, 0,133, 0, 0, 0,133, 0, 0, 0,133, 0, 0, 0,134, 0, 0, 0,
+134, 0, 0, 0,134, 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,
+136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,
+136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0,
+137, 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,
+138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,
+139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,
+141, 0, 0, 0,144, 0, 0, 0,141, 0, 0, 0,146, 0, 0, 0,149, 0, 0, 0,
+146, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,152, 0, 0, 0,
+151, 0, 0, 0,154, 0, 0, 0,160, 0, 0, 0,154, 0, 0, 0,162, 0, 0, 0,
+162, 0, 0, 0,162, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0,164, 0, 0, 0,
+172, 0, 0, 0,176, 0, 0, 0,172, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,
+178, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,
+179, 0, 0, 0,180, 0, 0, 0,180, 0, 0, 0,180, 0, 0, 0,181, 0, 0, 0,
+181, 0, 0, 0,181, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,
+183, 0, 0, 0,183, 0, 0, 0,183, 0, 0, 0,184, 0, 0, 0,184, 0, 0, 0,
+184, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,
+186, 0, 0, 0,186, 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,
+188, 0, 0, 0,188, 0, 0, 0,188, 0, 0, 0,189, 0, 0, 0,189, 0, 0, 0,
+189, 0, 0, 0,190, 0, 0, 0,190, 0, 0, 0,190, 0, 0, 0,191, 0, 0, 0,
+191, 0, 0, 0,191, 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,
+193, 0, 0, 0,193, 0, 0, 0,193, 0, 0, 0,194, 0, 0, 0,194, 0, 0, 0,
+194, 0, 0, 0,195, 0, 0, 0,195, 0, 0, 0,195, 0, 0, 0,196, 0, 0, 0,
+196, 0, 0, 0,196, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,
+198, 0, 0, 0,198, 0, 0, 0,198, 0, 0, 0,199, 0, 0, 0,199, 0, 0, 0,
+199, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,201, 0, 0, 0,
+201, 0, 0, 0,201, 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,
+203, 0, 0, 0,203, 0, 0, 0,203, 0, 0, 0,204, 0, 0, 0,204, 0, 0, 0,
+204, 0, 0, 0,205, 0, 0, 0,205, 0, 0, 0,205, 0, 0, 0,206, 0, 0, 0,
+206, 0, 0, 0,206, 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,
+208, 0, 0, 0,208, 0, 0, 0,208, 0, 0, 0,209, 0, 0, 0,209, 0, 0, 0,
+209, 0, 0, 0,210, 0, 0, 0,210, 0, 0, 0,210, 0, 0, 0,211, 0, 0, 0,
+211, 0, 0, 0,211, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,
+212, 0, 0, 0,212, 0, 0, 0,214, 0, 0, 0,227, 0, 0, 0,214, 0, 0, 0,
+235, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,
+237, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,
+238, 0, 0, 0,239, 0, 0, 0,239, 0, 0, 0,239, 0, 0, 0,240, 0, 0, 0,
+240, 0, 0, 0,240, 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,
+242, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,243, 0, 0, 0,243, 0, 0, 0,
+243, 0, 0, 0,244, 0, 0, 0,244, 0, 0, 0,244, 0, 0, 0,245, 0, 0, 0,
+245, 0, 0, 0,245, 0, 0, 0,246, 0, 0, 0,246, 0, 0, 0,246, 0, 0, 0,
+247, 0, 0, 0,247, 0, 0, 0,247, 0, 0, 0,248, 0, 0, 0,248, 0, 0, 0,
+248, 0, 0, 0,250, 0, 0, 0,254, 0, 0, 0,250, 0, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
+ 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0,
+ 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 5, 1, 0, 0,
+ 9, 1, 0, 0, 5, 1, 0, 0, 11, 1, 0, 0, 15, 1, 0, 0, 11, 1, 0, 0,
+ 17, 1, 0, 0, 17, 1, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 18, 1, 0, 0,
+ 18, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0,
+ 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 20, 1, 0, 0, 20, 1, 0, 0,
+ 20, 1, 0, 0, 21, 1, 0, 0, 21, 1, 0, 0, 21, 1, 0, 0, 22, 1, 0, 0,
+ 22, 1, 0, 0, 22, 1, 0, 0, 24, 1, 0, 0, 29, 1, 0, 0, 24, 1, 0, 0,
+ 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0,
+ 31, 1, 0, 0, 31, 1, 0, 0, 31, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0,
+ 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0,
+ 32, 1, 0, 0, 34, 1, 0, 0, 42, 1, 0, 0, 34, 1, 0, 0, 44, 1, 0, 0,
+ 48, 1, 0, 0, 44, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0,
+ 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 51, 1, 0, 0, 51, 1, 0, 0,
+ 51, 1, 0, 0, 52, 1, 0, 0, 52, 1, 0, 0, 52, 1, 0, 0, 53, 1, 0, 0,
+ 53, 1, 0, 0, 53, 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0,
+ 55, 1, 0, 0, 55, 1, 0, 0, 55, 1, 0, 0, 56, 1, 0, 0, 56, 1, 0, 0,
+ 56, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0,
+ 57, 1, 0, 0, 57, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0,
+ 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0,
+ 59, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0,
+ 60, 1, 0, 0, 60, 1, 0, 0, 60, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0,
+ 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0,
+ 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0,
+ 62, 1, 0, 0, 62, 1, 0, 0, 63, 1, 0, 0, 63, 1, 0, 0, 63, 1, 0, 0,
+ 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0, 64, 1, 0, 0,
+ 64, 1, 0, 0, 64, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0,
+ 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 66, 1, 0, 0,
+ 66, 1, 0, 0, 66, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0,
+ 68, 1, 0, 0, 68, 1, 0, 0, 68, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0,
+ 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0,
+ 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0, 70, 1, 0, 0,
+ 70, 1, 0, 0, 70, 1, 0, 0, 71, 1, 0, 0, 71, 1, 0, 0, 71, 1, 0, 0,
+ 72, 1, 0, 0, 72, 1, 0, 0, 72, 1, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101, 79,110,101,
+ 68,101,115,116, 0, 1, 0, 0, 0,143, 1, 0, 0, 18, 0, 0, 0, 0, 0, 0,
+ 0, 84,119,111, 83,111,117,114, 99,101,115, 79,110,101, 68,101,115,116, 0, 2,
+ 0, 0, 0,143, 1, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 84,104,114,101,101,
+ 83,111,117,114, 99,101,115, 79,110,101, 68,101,115,116, 0, 3, 0, 0, 0,143,
+ 1, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101,
+ 84,119,111, 68,101,115,116,115, 0, 4, 0, 0, 0,143, 1, 0, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 79,110,101, 83,111,117,114, 99,101, 84,104,114,101,101, 68,
+101,115,116,115, 0, 5, 0, 0, 0,143, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0,
+ 0,104,111,117,103,104, 95,104,101,105,103,104,116, 0, 6, 0, 0, 0,143, 1,
+ 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,105,110,116, 95,100, 97,116, 97,116,121,
+112,101, 0,182, 0, 0, 0,143, 1, 0, 0, 0, 0, 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_process51/im_process_le64.lo")==0) lua_call(L, 0, 0);
+}
diff --git a/im/src/lua5/loh/im_process_le64w.loh b/im/src/lua5/loh/im_process_le64w.loh
new file mode 100755
index 0000000..b94506a
--- /dev/null
+++ b/im/src/lua5/loh/im_process_le64w.loh
@@ -0,0 +1,890 @@
+/* code automatically generated by bin2c -- DO NOT EDIT */
+{
+/* #include'ing this file in a C program is equivalent to calling
+ if (luaL_loadfile(L,"../obj/imlua_process51/im_process_le64w.lo")==0) lua_pcall(L, 0, 0, 0);
+*/
+/* ../obj/imlua_process51/im_process_le64w.lo */
+static const unsigned char B1[]={
+ 27, 76,117, 97, 81, 0, 1, 4, 8, 4, 8, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 64,108,117, 97, 53, 47,105,109, 95,112,114,111, 99,101,115,115, 46,108,117, 97,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13,135, 1, 0, 0, 36, 0, 0,
+ 0,100, 64, 0, 0,164,128, 0, 0,228,192, 0, 0, 36, 1, 1, 0,100, 65, 1,
+ 0,128, 1, 0, 0,193, 1, 0, 0, 3, 2, 0, 5,197, 66, 0, 0,198,130,192,
+ 5,156, 65, 0, 3,128, 1, 0, 0,193,193, 0, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 1, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 1, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 1, 0, 1,194, 1, 0, 64, 2,128, 2,133, 66, 0,
+ 0,134, 2, 66, 5,197, 66, 0, 0,198, 66,194, 5,156, 65, 0, 3,128, 1, 0,
+ 0,193,129, 2, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 2, 0, 3, 2, 0,
+ 5,197, 66, 0, 0,198, 2,195, 5,156, 65, 0, 3,128, 1, 0, 0,193, 65, 3,
+ 0, 3, 2,128, 4,133, 66, 0, 0,134,130, 67, 5,195, 2,128, 5,156, 65, 0,
+ 3,133, 65, 0, 0,228,129, 1, 0,137,193,129,135,133, 65, 0, 0,228,193, 1,
+ 0,137,193, 1,136,128, 1, 0, 0,193, 65, 4, 0, 36, 2, 2, 0,100, 66, 2,
+ 0,156, 65, 0, 2,133, 65, 0, 0,228,129, 2, 0,137,193, 1,137,128, 1,128,
+ 0,193,193, 4, 0,156, 65, 0, 1,133, 65, 0, 0,228,193, 2, 0,137,193, 1,
+138,133, 65, 0, 0,228, 1, 3, 0,137,193,129,138,128, 1, 0, 0,193,129, 5,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 5, 0, 36, 66, 3, 0,100,130, 3,
+ 0,156, 65, 0, 2,128, 1, 0, 0,193, 1, 6, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 65, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 6, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 6, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 7,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 7, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 7, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 7, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 1, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 8,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 8, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 8, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 9, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 65, 9, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 9,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 9, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 1, 10, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 10, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,129, 10, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 10,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 11, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193, 65, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 11, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193,193, 11, 0,156, 65, 0, 1,128, 1, 0, 0,193, 1, 12,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 12, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,129, 12, 0,156, 65, 0, 1,128, 1, 0, 0,193,193, 12, 0,156, 65, 0,
+ 1,128, 1, 0, 0,193, 1, 13, 0,156, 65, 0, 1,128, 1, 0, 0,193, 65, 13,
+ 0,156, 65, 0, 1,128, 1, 0, 0,193,129, 13, 0,156, 65, 0, 1,128, 1, 0,
+ 0,193,193, 13, 0,156, 65, 0, 1,128, 1,128, 1,193, 1, 14, 0, 3, 2, 0,
+ 4,100,194, 3, 0,156, 65, 0, 2,133, 65, 0, 0,228, 1, 4, 0,137,193,129,
+156,164, 65, 4, 0,192, 1, 0, 0, 1,130, 14, 0, 67, 2,128, 5, 0, 3, 0,
+ 3,220, 65, 0, 3,192, 1, 0, 0, 1,194, 14, 0, 67, 2,128, 5, 0, 3, 0,
+ 3,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 15, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 66, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 15, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1,194, 15, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 16,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 16, 0,220, 65, 0, 1,192, 1,128,
+ 0, 1,130, 16, 0,220, 65, 0, 1,197, 65, 0, 0, 36,130, 4, 0,201, 1,130,
+161,192, 1,128, 0, 1, 2, 17, 0,220, 65, 0, 1,192, 1, 0, 1, 1, 66, 17,
+ 0,220, 65, 0, 1,192, 1,128, 1, 1,130, 17, 0,220, 65, 0, 1,192, 1,128,
+ 0, 1,194, 17, 0, 67, 2,128, 5, 5, 67, 0, 0, 6, 3, 82, 6,220, 65, 0,
+ 3,197, 65, 0, 0, 36,194, 4, 0,201, 1,130,164,197, 65, 0, 0, 36, 2, 5,
+ 0,201, 1, 2,165,192, 1,128, 0, 1,194, 18, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 2, 19, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 19, 0, 67, 2, 0,
+ 5,197, 66, 0, 0,198,130,211, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1,194, 19, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 20, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 66, 20, 0,220, 65, 0, 1,197, 65, 0, 0, 36, 66, 5,
+ 0,201, 1, 2,169,192, 1, 0, 2, 1,194, 20, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198, 2,194, 5, 5, 67, 0, 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0,
+ 1, 1, 2, 21, 0, 67, 2, 0, 5,197, 66, 0, 0,198, 66,213, 5, 5, 67, 0,
+ 0, 6,131, 85, 6,220, 65, 0, 3,197, 65, 0, 0, 36,130, 5, 0,201, 1,130,
+171,197, 65, 0, 0, 36,194, 5, 0,201, 1, 2,172,192, 1, 0, 0, 1, 66, 22,
+ 0, 67, 2,128, 5, 5, 67, 0, 0, 6, 3, 67, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1,130, 22, 0,220, 65, 0, 1,192, 1,128, 0, 1,194, 22, 0,220, 65, 0,
+ 1,192, 1, 0, 0, 1, 2, 23, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 66, 23,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 23, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1,194, 23, 0,220, 65, 0, 1,192, 1, 0, 0, 1, 2, 24, 0, 67, 2,128,
+ 5, 5, 67, 0, 0, 6,131, 85, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 24,
+ 0, 67, 2,128, 5, 5, 67, 0, 0, 6,131, 85, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1,130, 24, 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 24, 0, 67, 2, 0,
+ 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0,
+ 0, 1, 2, 25, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0,
+ 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 25, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1,128, 0, 1,130, 25,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 25, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1, 2, 26,
+ 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0,
+ 3,192, 1, 0, 0, 1, 66, 26, 0,220, 65, 0, 1,192, 1, 0, 0, 1,130, 26,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 26, 0,220, 65, 0, 1,192, 1, 0,
+ 0, 1, 2, 27, 0, 67, 2, 0, 5,197, 66, 0, 0,198,130,195, 5, 3, 3, 0,
+ 6,220, 65, 0, 3,192, 1, 0, 0, 1, 66, 27, 0, 67, 2, 0, 5,197, 66, 0,
+ 0,198,130,195, 5, 3, 3, 0, 6,220, 65, 0, 3,192, 1, 0, 0, 1,130, 27,
+ 0,220, 65, 0, 1,192, 1, 0, 0, 1,194, 27, 0,220, 65, 0, 1, 30, 0,128,
+ 0,112, 0, 0, 0, 4, 19, 0, 0, 0, 0, 0, 0, 0, 65,110, 97,108,121,122,
+101, 70,105,110,100, 82,101,103,105,111,110,115, 0, 4, 3, 0, 0, 0, 0, 0,
+ 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 85, 83, 72, 79, 82, 84,
+ 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114,
+105,109,101,116,101,114, 76,105,110,101, 0, 4, 13, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 80,114,117,110,101, 0, 4, 17, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 70,105,108,108, 72,111,108,101,115, 0, 4,
+ 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 72,111,117,103,104,
+ 76,105,110,101,115, 0, 3, 0, 0, 0, 0, 0,128,102, 64, 4, 5, 0, 0, 0,
+ 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 73, 78,
+ 84, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 72,111,
+117,103,104, 76,105,110,101,115, 68,114, 97,119, 0, 4, 25, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 68,105,115,116, 97,110, 99,101, 84,114, 97,
+110,115,102,111,114,109, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 70, 76, 79, 65,
+ 84, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,
+103,105,111,110, 97,108, 77, 97,120,105,109,117,109, 0, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 66, 73, 78, 65, 82, 89, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 82,101,100,117, 99,101, 78,101,119, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,115,105,122,101, 78,101,
+119, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,
+100,117, 99,101, 66,121, 52, 0, 4, 15, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 67,114,111,112, 78,101,119, 0, 4, 14, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 73,110,115,101,114,116, 0, 4, 21, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,100,100, 77, 97,114,103,105,110,
+115, 78,101,119, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,111,116, 97,116,101, 78,101,119, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 82,111,116, 97,116,101, 82,101,102, 0, 4, 16, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,116, 97,116,101, 57,
+ 48, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,111,
+116, 97,116,101, 49, 56, 48, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 77,105,114,114,111,114, 0, 4, 12, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 70,108,105,112, 0, 4, 14, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 82, 97,100,105, 97,108, 0, 4, 25, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104,
+ 67,111,110,118,111,108,118,101, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 69,114,111,100,101, 0,
+ 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121,
+ 77,111,114,112,104, 68,105,108, 97,116,101, 0, 4, 21, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 79,112,101,
+110, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114,
+ 97,121, 77,111,114,112,104, 67,108,111,115,101, 0, 4, 23, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104, 84,111,
+112, 72, 97,116, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 71,114, 97,121, 77,111,114,112,104, 87,101,108,108, 0, 4, 25, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71,114, 97,121, 77,111,114,112,104,
+ 71,114, 97,100,105,101,110,116, 0, 4, 24, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,111,110,118,111,108,118,
+101, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,
+110, 77,111,114,112,104, 69,114,111,100,101, 0, 4, 22, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 68,105,108, 97,
+116,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,
+105,110, 77,111,114,112,104, 79,112,101,110, 0, 4, 21, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 67,108,111,115,
+101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,
+110, 77,111,114,112,104, 79,117,116,108,105,110,101, 0, 4, 20, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,110, 77,111,114,112,104, 84,104,
+105,110, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,
+101,100,105, 97,110, 67,111,110,118,111,108,118,101, 0, 4, 21, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,111,110,118,111,
+108,118,101, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 82, 97,110,107, 67,108,111,115,101,115,116, 67,111,110,118,111,108,118,101, 0,
+ 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,107,
+ 77, 97,120, 67,111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 82, 97,110,107, 77,105,110, 67,111,110,118,111,
+108,118,101, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 67,111,110,118,111,108,118,101, 0, 4, 19, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 67,111,110,118,111,108,118,101, 83,101,112, 0, 4, 19, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,110,118,111,108,118,
+101, 82,101,112, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 67,111,110,118,111,108,118,101, 68,117, 97,108, 0, 4, 23, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 67,111,109,112, 97,115,115, 67,111,110,
+118,111,108,118,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 77,101, 97,110, 67,111,110,118,111,108,118,101, 0, 4, 24, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 71, 97,117,115,115,105, 97,110, 67,
+111,110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 66, 97,114,108,101,116,116, 67,111,110,118,111,108,118,101, 0,
+ 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,116,101,
+114,108, 97, 99,101, 83,112,108,105,116, 0, 4, 25, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 73,110,116,101,114,108, 97, 99,101, 83,112,108,105,
+116, 78,101,119, 0, 4, 30, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 68,105,102,102, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,110,118,111,
+108,118,101, 0, 4, 29, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 76, 97,112, 79,102, 71, 97,117,115,115,105, 97,110, 67,111,110,118,111,108,118,
+101, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,111,
+ 98,101,108, 67,111,110,118,111,108,118,101, 0, 4, 26, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 83,112,108,105,110,101, 69,100,103,101, 67,111,
+110,118,111,108,118,101, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 80,114,101,119,105,116,116, 67,111,110,118,111,108,118,101, 0, 4,
+ 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 90,101,114,111, 67,
+114,111,115,115,105,110,103, 0, 4, 13, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 67, 97,110,110,121, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 85,110, 65,114,105,116,104,109,101,116,105, 99, 79,112,
+ 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,114,105,
+116,104,109,101,116,105, 99, 79,112, 0, 4, 28, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 65,114,105,116,104,109,101,116,105, 99, 67,111,110,115,
+116, 79,112, 78,101,119, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 66,108,101,110,100, 67,111,110,115,116, 0, 4, 13, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 66,108,101,110,100, 0, 4, 20, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,
+112,108,101,120, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 77,101,114,103,101, 67,111,109,112,108,101,120, 0, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 67, 70, 76, 79, 65, 84, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 77,117,108,116,105,112,108,101, 77,101, 97,110, 78,101,
+119, 0, 4, 25, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,117,
+108,116,105,112,108,101, 83,116,100, 68,101,118, 78,101,119, 0, 4, 22, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,117,116,111, 67,111,118, 97,
+114,105, 97,110, 99,101, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 77,117,108,116,105,112,108,121, 67,111,110,106, 0, 4, 26, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 81,117, 97,110,116,105,122,101,
+ 82, 71, 66, 85,110,105,102,111,114,109, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+ 77, 65, 80, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 81,117, 97,110,116,105,122,101, 71,114, 97,121, 85,110,105,102,111,114,109, 0,
+ 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 69,120,112, 97,
+110,100, 72,105,115,116,111,103,114, 97,109, 0, 4, 25, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 69,113,117, 97,108,105,122,101, 72,105,115,116,
+111,103,114, 97,109, 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 83,112,108,105,116, 89, 67,104,114,111,109, 97, 78,101,119, 0, 4, 16,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 72,
+ 83, 73, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,
+101,114,103,101, 72, 83, 73, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 82, 71, 66,
+ 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 66, 89, 84, 69, 0, 4, 26, 0, 0, 0,
+ 0, 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,
+111,110,101,110,116,115, 78,101,119, 0, 4, 26, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 77,101,114,103,101, 67,111,109,112,111,110,101,110,116,
+115, 78,101,119, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 78,111,114,109, 97,108,105,122,101, 67,111,109,112,111,110,101,110,116,115,
+ 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82,101,112,
+108, 97, 99,101, 67,111,108,111,114, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 66,105,116,119,105,115,101, 79,112, 0, 4, 18, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,105,116,119,105,115,101, 78,
+111,116, 0, 4, 15, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 66,
+105,116, 77, 97,115,107, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 66,105,116, 80,108, 97,110,101, 0, 4, 17, 0, 0, 0, 0, 0, 0,
+ 0, 80,114,111, 99,101,115,115, 84,111,110,101, 71, 97,109,117,116, 0, 4, 19,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 85,110, 78,111,114,109,
+ 97,108,105,122,101, 0, 4, 18, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,
+115,115, 68,105,114,101, 99,116, 67,111,110,118, 0, 4, 16, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 78,101,103, 97,116,105,118,101, 0, 4, 30,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 82, 97,110,103,101, 67,
+111,110,116,114, 97,115,116, 84,104,114,101,115,104,111,108,100, 0, 4, 25, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 76,111, 99, 97,108, 77, 97,
+120, 84,104,114,101,115,104,111,108,100, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 84,104,114,101,115,104,111,108,100, 0, 4, 23, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 84,104,114,101,115,104,111,
+108,100, 66,121, 68,105,102,102, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 72,121,115,116,101,114,101,115,105,115, 84,104,114,101,115,
+104,111,108,100, 0, 4, 27, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 85,110,105,102,111,114,109, 69,114,114, 84,104,114,101,115,104,111,108,100,
+ 0, 4, 28, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 68,105,102,
+117,115,105,111,110, 69,114,114, 84,104,114,101,115,104,111,108,100, 0, 4, 24,
+ 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 80,101,114, 99,101,110,
+116, 84,104,114,101,115,104,111,108,100, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0,
+ 80,114,111, 99,101,115,115, 79,116,115,117, 84,104,114,101,115,104,111,108,100,
+ 0, 4, 23, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 77,105,110,
+ 77, 97,120, 84,104,114,101,115,104,111,108,100, 0, 4, 22, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 83,108,105, 99,101, 84,104,114,101,115,104,
+111,108,100, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 80,105,120,101,108, 97,116,101, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 80,111,115,116,101,114,105,122,101, 0, 24, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 25, 0, 0, 0, 0, 5, 0, 9, 17,
+ 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156,
+ 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36,
+ 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0,
+ 0,128, 2,137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,
+114,116, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 5, 1, 7, 8,
+ 23, 0, 0, 0,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0,
+ 68, 1,128, 0,132, 1, 0, 1,196, 1,128, 1,156,128, 0, 3,196, 0, 0, 2,
+ 0, 1, 0, 0, 64, 1, 0, 1,133,129, 0, 0,192, 1,128, 0,156, 1, 0, 1,
+220,128, 0, 0,218, 0, 0, 0, 22,192, 0,128, 0, 1,128, 1, 64, 1, 0, 1,
+ 30, 1,128, 1, 22, 0, 0,128,158, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0,
+ 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0,
+ 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7,
+ 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0,
+ 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 18, 0,
+ 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0, 0, 0, 18, 0,
+ 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 20, 0,
+ 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 22, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0,
+ 22, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,
+101, 0, 8, 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,
+116, 0, 15, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0,119,105,100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,
+104,116, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97,
+ 99,101, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 9, 0,
+ 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 13, 0,
+ 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 24, 0,
+ 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0,
+ 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,
+110, 99,110, 97,109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97,
+ 95,116,121,112,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0,102,117,110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 50, 0, 0, 0, 0, 5, 0, 11, 22,
+ 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2, 5,
+130, 0, 0, 6,194, 64, 4, 65, 2, 1, 0,128, 2, 0, 0, 28, 2,128, 1,156,
+ 65, 0, 0,133, 1, 0, 0,192, 1, 0, 0, 1, 66, 1, 0,213, 1,130, 3, 36,
+ 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0,
+ 0,128, 2,137, 1,130, 3, 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,
+114,116, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,115,116,114,105,110,103, 0, 4,
+ 7, 0, 0, 0, 0, 0, 0, 0,102,111,114,109, 97,116, 0, 4, 24, 0, 0, 0,
+ 0, 0, 0, 0,117,110,100,101,102,105,110,101,100, 32,102,117,110, 99,116,105,
+111,110, 32, 96, 37,115, 39, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0,
+ 0, 5, 2, 7, 10, 24, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0,
+ 0, 68, 1, 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0,
+ 3, 4, 1, 0, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 5,130, 0,
+ 0, 64, 2, 0, 1, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22,192, 0,
+128, 64, 1, 0, 2,128, 1,128, 1, 94, 1,128, 1, 22, 0, 0,128,222, 0, 0,
+ 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97,
+ 99,107, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40,
+ 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40,
+ 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43,
+ 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 44, 0, 0, 0, 44,
+ 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 47,
+ 0, 0, 0, 49, 0, 0, 0, 5, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,
+114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 23, 0, 0, 0, 11, 0,
+ 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50, 0, 0, 0, 0,
+ 0, 23, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0,
+ 0, 23, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,
+103,101, 0, 8, 0, 0, 0, 23, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,
+101,116, 0, 16, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0,119,105,100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,
+103,104,116, 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112,
+ 97, 99,101, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,
+101, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 22, 0, 0, 0, 32,
+ 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35,
+ 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 38,
+ 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 49,
+ 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49,
+ 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,
+117,110, 99,110, 97,109,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 21, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 21, 0, 0,
+ 0, 12, 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101,
+ 0, 0, 0, 0, 0, 21, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116,
+ 97, 95,116,121,112,101, 0, 0, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0,102,117,110, 99, 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 73, 0, 0, 0, 0, 5, 0, 9,
+ 17, 0, 0, 0, 69, 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,
+156, 65, 0, 1,133, 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3,
+ 36, 2, 0, 0, 0, 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2,
+ 0, 0,128, 2,137, 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0,
+ 0, 0, 0, 0, 0,105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,
+101,114,116, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 72, 0, 0, 0, 5, 3, 7,
+ 12, 25, 0, 0, 0, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0,
+ 0,196, 1,128, 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0,
+ 2,128, 1, 0, 0,192, 1,128, 0, 0, 2, 0, 1, 64, 2, 0, 2,133,130, 0,
+ 0,192, 2,128, 1,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22,192, 0,
+128,128, 1,128, 2,192, 1, 0, 2,158, 1,128, 1, 22, 0, 0,128, 30, 1, 0,
+ 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,
+101, 66, 97,115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97,
+ 99,107, 0, 0, 0, 0, 0, 25, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66,
+ 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 67,
+ 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68,
+ 0, 0, 0, 70, 0, 0, 0, 72, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 49, 0, 0, 0, 0, 0, 24, 0,
+ 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 50,
+ 0, 0, 0, 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,115,114, 99,
+ 95,105,109, 97,103,101, 51, 0, 0, 0, 0, 0, 24, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 24, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 8, 0, 0, 0, 24, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 17, 0, 0, 0, 24, 0,
+ 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0, 0, 0, 0,
+ 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0,102,117,110, 99, 0, 17, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 58, 0,
+ 0, 0, 58, 0, 0, 0, 58, 0, 0, 0, 61, 0, 0, 0, 61, 0, 0, 0, 61, 0,
+ 0, 0, 61, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0,
+ 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 73, 0, 0, 0, 6, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,101, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,
+103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99, 0, 2,
+ 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,
+ 0, 0, 0, 97, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69, 1, 0, 0, 70,
+ 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133, 1, 0, 0,192,
+ 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0, 0,128, 0, 0,
+ 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137, 1,130, 3, 30,
+ 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4,
+ 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4, 4, 0, 0, 0,
+ 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 84, 0, 0, 0, 96, 0, 0, 0, 5, 1, 7, 10, 35, 0, 0, 0,133, 0, 0, 0,
+134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,132, 1, 0, 1,
+196, 1,128, 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0,
+ 68, 1, 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,220,128, 0, 3,
+ 4, 1, 0, 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1, 5,130, 0, 0,
+ 64, 2,128, 0, 28, 2, 0, 1, 28,129, 0, 0, 26, 1, 0, 0, 22, 0, 1,128,
+ 64, 1, 0, 2,128, 1, 0, 1,192, 1,128, 1, 94, 1, 0, 2, 22,128, 0,128,
+ 64, 1, 0, 1,128, 1,128, 1, 94, 1,128, 1, 30, 0,128, 0, 3, 0, 0, 0,
+ 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0,
+ 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 7,
+ 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,107, 0, 0, 0, 0, 0, 35, 0,
+ 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0,
+ 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 86, 0, 0, 0, 87, 0, 0, 0, 87, 0,
+ 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0,
+ 0, 0, 87, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0,
+ 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 91, 0,
+ 0, 0, 91, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0,
+ 0, 0, 92, 0, 0, 0, 94, 0, 0, 0, 94, 0, 0, 0, 94, 0, 0, 0, 96, 0,
+ 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 97,114,103, 0, 0, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,
+100,115,116, 95,105,109, 97,103,101, 49, 0, 8, 0, 0, 0, 34, 0, 0, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 50, 0, 16, 0,
+ 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 24, 0,
+ 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,
+100,116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12,
+ 0, 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0, 80, 0, 0, 0, 80, 0,
+ 0, 0, 81, 0, 0, 0, 81, 0, 0, 0, 81, 0, 0, 0, 84, 0, 0, 0, 84, 0,
+ 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0,
+ 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 97, 0,
+ 0, 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,
+109,101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,
+105,100,116,104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+ 0,104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0,
+ 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,
+101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,
+110, 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,103, 0, 0, 0,122, 0, 0, 0, 0, 5, 0, 9, 17, 0, 0, 0, 69,
+ 1, 0, 0, 70, 1,128, 2,133, 65, 0, 0,192, 1,128, 2,156, 65, 0, 1,133,
+ 1, 0, 0,192, 1, 0, 0, 1,130, 0, 0,213, 1,130, 3, 36, 2, 0, 0, 0,
+ 0,128, 0, 0, 0, 0, 1, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2,137,
+ 1,130, 3, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,
+105,109, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 97,115,115,101,114,116, 0, 4,
+ 4, 0, 0, 0, 0, 0, 0, 0, 78,101,119, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,108, 0, 0, 0,121, 0, 0, 0, 5, 1, 7, 12, 46, 0, 0, 0,
+133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0, 4, 1, 0, 0, 68, 1,128, 0,
+132, 1, 0, 1,196, 1,128, 1,156,128, 0, 3,197, 0, 0, 0,198, 64,192, 1,
+ 0, 1, 0, 0, 68, 1, 0, 0,132, 1,128, 0,196, 1, 0, 1, 4, 2,128, 1,
+220,128, 0, 3, 5, 1, 0, 0, 6, 65, 64, 2, 64, 1, 0, 0,132, 1, 0, 0,
+196, 1,128, 0, 4, 2, 0, 1, 68, 2,128, 1, 28,129, 0, 3, 68, 1, 0, 2,
+128, 1, 0, 0,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,133,130, 0, 0,
+192, 2,128, 0,156, 2, 0, 1, 92,129, 0, 0, 90, 1, 0, 0, 22, 64, 1,128,
+128, 1,128, 2,192, 1, 0, 1, 0, 2,128, 1, 64, 2, 0, 2,158, 1,128, 2,
+ 22,192, 0,128,128, 1, 0, 1,192, 1,128, 1, 0, 2, 0, 2,158, 1, 0, 2,
+ 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0,
+ 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101,
+ 66, 97,115,101,100, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,
+107, 0, 0, 0, 0, 0, 46, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0,
+ 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0, 0, 0,110, 0,
+ 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0,
+ 0, 0,111, 0, 0, 0,111, 0, 0, 0,111, 0, 0, 0,112, 0, 0, 0,112, 0,
+ 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0, 0, 0,112, 0,
+ 0, 0,112, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0,
+ 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0, 0, 0,115, 0,
+ 0, 0,116, 0, 0, 0,116, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0,
+ 0, 0,117, 0, 0, 0,117, 0, 0, 0,117, 0, 0, 0,119, 0, 0, 0,119, 0,
+ 0, 0,119, 0, 0, 0,119, 0, 0, 0,121, 0, 0, 0, 6, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0,
+ 45, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0,
+ 45, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,
+101, 49, 0, 8, 0, 0, 0, 45, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,
+115,116, 95,105,109, 97,103,101, 50, 0, 16, 0, 0, 0, 45, 0, 0, 0, 11, 0,
+ 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 51, 0, 24, 0, 0,
+ 0, 45, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,114,101,116, 0, 33, 0, 0,
+ 0, 45, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,
+116,104, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0,102,117,110, 99, 0, 17, 0, 0, 0,104, 0, 0, 0,104, 0, 0,
+ 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,108, 0, 0, 0,108, 0, 0,
+ 0,108, 0, 0, 0,108, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0,
+ 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,121, 0, 0, 0,122, 0, 0,
+ 0, 6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,102,117,110, 99,110, 97,109,
+101, 0, 0, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,
+100,116,104, 0, 0, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+104,101,105,103,104,116, 0, 0, 0, 0, 0, 16, 0, 0, 0, 12, 0, 0, 0, 0,
+ 0, 0, 0, 99,111,108,111,114, 95,115,112, 97, 99,101, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97, 95,116,121,112,101,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,102,117,110,
+ 99, 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,126, 0, 0, 0,130, 0, 0, 0, 0, 1, 0, 7, 18, 0, 0, 0,100, 0,
+ 0, 0,133, 0, 0, 0,134, 64, 64, 1,192, 0,128, 0, 11,129, 64, 0, 28, 1,
+ 0, 1,220,128, 0, 0, 0, 1,128, 0, 75,193, 64, 0, 92, 1, 0, 1, 28,129,
+ 0, 0,204, 0,129, 1,156,128, 0, 1,143, 0, 65, 1,206,128, 0,130,204, 64,
+193, 1,222, 0, 0, 1, 30, 0,128, 0, 6, 0, 0, 0, 4, 5, 0, 0, 0, 0,
+ 0, 0, 0,109, 97,116,104, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,115,113,114,
+116, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 4, 7, 0,
+ 0, 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 64, 3, 0, 0, 0, 0, 0, 0,240, 63, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 78,
+ 0, 0, 0, 94, 0, 0, 1, 30, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0,127, 0, 0, 0, 1, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0,120, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
+ 0, 18, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,
+ 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,
+ 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,128, 0, 0,
+ 0,129, 0, 0, 0,129, 0, 0, 0,129, 0, 0, 0,130, 0, 0, 0, 3, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 17,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,115,113,114, 0, 1, 0, 0, 0, 17,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,114,109, 97,120, 0, 14, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,141, 0, 0, 0,
+144, 0, 0, 0, 0, 3, 0, 7, 14, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1,
+ 0, 1, 0, 0, 64, 1,128, 0,128, 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0,
+ 6,129, 64, 2, 64, 1, 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1,
+ 30, 1,128, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0,
+ 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,
+101, 97,116,101, 66, 97,115,101,100, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,
+114,111, 99,101,115,115, 82,101,100,117, 99,101, 0, 0, 0, 0, 0, 14, 0, 0,
+ 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0,
+ 0,142, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0,
+ 0,143, 0, 0, 0,143, 0, 0, 0,143, 0, 0, 0,144, 0, 0, 0, 4, 0, 0,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0,
+ 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,
+103,104,116, 0, 0, 0, 0, 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+100,115,116, 95,105,109, 97,103,101, 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,146, 0, 0, 0,149, 0, 0, 0, 0, 3,
+ 0, 7, 14, 0, 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0, 64, 1,
+128, 0,128, 1, 0, 1,220,128, 0, 2, 5, 1, 0, 0, 6,129, 64, 2, 64, 1,
+ 0, 0,128, 1,128, 1, 28,129,128, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,
+128, 0, 3, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17,
+ 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,
+115,101,100, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115,
+ 82,101,115,105,122,101, 0, 0, 0, 0, 0, 14, 0, 0, 0,147, 0, 0, 0,147,
+ 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,147, 0, 0, 0,148,
+ 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148, 0, 0, 0,148,
+ 0, 0, 0,148, 0, 0, 0,149, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 0, 0, 0, 0, 13,
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 0, 0,
+ 0, 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109,
+ 97,103,101, 0, 6, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0, 0, 1, 0, 3, 5, 0, 0, 0,
+ 75, 0, 64, 0, 92,128, 0, 1, 79, 64,192, 0, 94, 0, 0, 1, 30, 0,128, 0,
+ 2, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,104, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 5, 0, 0, 0,151, 0, 0, 0,
+151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0, 1, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 0, 0, 0,152, 0,
+ 0, 0, 0, 1, 0, 3, 5, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1, 79, 64,
+192, 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0, 0, 0,
+ 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0, 64, 0,
+ 0, 0, 0, 5, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152, 0, 0, 0,152,
+ 0, 0, 0,152, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,
+109, 97,103,101, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,154, 0, 0, 0,160, 0, 0, 0, 0, 5, 0, 13, 19, 0, 0,
+ 0, 77, 65, 0, 1, 76, 1,192, 2,141,193, 0, 1,140, 1, 64, 3,197, 65, 0,
+ 0,198,129,192, 3, 0, 2, 0, 0, 64, 2,128, 2,128, 2, 0, 3,220,129, 0,
+ 2, 5, 66, 0, 0, 6,194, 64, 4, 64, 2, 0, 0,128, 2,128, 3,192, 2,128,
+ 0, 0, 3,128, 1, 28, 66,128, 2,222, 1, 0, 1, 30, 0,128, 0, 4, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,
+109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,
+116,101, 66, 97,115,101,100, 0, 4, 12, 0, 0, 0, 0, 0, 0, 0, 80,114,111,
+ 99,101,115,115, 67,114,111,112, 0, 0, 0, 0, 0, 19, 0, 0, 0,155, 0, 0,
+ 0,155, 0, 0, 0,156, 0, 0, 0,156, 0, 0, 0,157, 0, 0, 0,157, 0, 0,
+ 0,157, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,157, 0, 0, 0,158, 0, 0,
+ 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,158, 0, 0,
+ 0,158, 0, 0, 0,159, 0, 0, 0,160, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 18,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,120,109,105,110, 0, 0, 0, 0, 0,
+ 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,120,109, 97,120, 0, 0, 0, 0,
+ 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,121,109,105,110, 0, 0, 0,
+ 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,121,109, 97,120, 0, 0,
+ 0, 0, 0, 18, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,119,105,100,116,104,
+ 0, 2, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,
+103,104,116, 0, 4, 0, 0, 0, 18, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+100,115,116, 95,105,109, 97,103,101, 0, 10, 0, 0, 0, 18, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0, 0, 5,
+ 0, 13, 19, 0, 0, 0, 77, 65, 0, 1, 76, 1,192, 2,141,193, 0, 1,140, 1,
+ 64, 3,197, 65, 0, 0,198,129,192, 3, 0, 2, 0, 0, 64, 2,128, 2,128, 2,
+ 0, 3,220,129, 0, 2, 5, 66, 0, 0, 6,194, 64, 4, 64, 2, 0, 0,128, 2,
+128, 3,192, 2,128, 0, 0, 3,128, 1, 28, 66,128, 2,222, 1, 0, 1, 30, 0,
+128, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 3, 0, 0, 0,
+ 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,
+101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 18, 0, 0, 0, 0, 0,
+ 0, 0, 80,114,111, 99,101,115,115, 65,100,100, 77, 97,114,103,105,110,115, 0,
+ 0, 0, 0, 0, 19, 0, 0, 0,165, 0, 0, 0,165, 0, 0, 0,166, 0, 0, 0,
+166, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,167, 0, 0, 0,
+167, 0, 0, 0,167, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,
+168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0,
+170, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,
+105,109, 97,103,101, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0,120,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0,120,109, 97,120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0,121,109,105,110, 0, 0, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0,121,109, 97,120, 0, 0, 0, 0, 0, 18, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0,119,105,100,116,104, 0, 2, 0, 0, 0, 18, 0, 0, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0,104,101,105,103,104,116, 0, 4, 0, 0, 0, 18,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101,
+ 0, 10, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,172, 0, 0, 0,176, 0, 0, 0, 0, 4, 0, 13, 26, 0, 0, 0, 5, 1, 0,
+ 0, 6, 65, 64, 2, 75,129, 64, 0, 92,129, 0, 1,139,193, 64, 0,156,129, 0,
+ 1,192, 1,128, 0, 0, 2, 0, 1, 28,193,128, 2,133, 1, 0, 0,134, 1, 65,
+ 3,192, 1, 0, 0, 0, 2, 0, 2, 64, 2,128, 2,156,129, 0, 2,197, 1, 0,
+ 0,198, 65,193, 3, 0, 2, 0, 0, 64, 2, 0, 3,128, 2,128, 0,192, 2, 0,
+ 1, 0, 3,128, 1,220,129, 0, 3, 0, 2, 0, 3,222, 1,128, 1, 30, 0,128,
+ 0, 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 22, 0,
+ 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 67, 97,108, 99, 82,111,116,
+ 97,116,101, 83,105,122,101, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,
+116,104, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 4,
+ 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66,
+ 97,115,101,100, 0, 4, 14, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,
+115, 82,111,116, 97,116,101, 0, 0, 0, 0, 0, 26, 0, 0, 0,173, 0, 0, 0,
+173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,
+173, 0, 0, 0,173, 0, 0, 0,173, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,
+174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0,
+175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,
+175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,175, 0, 0, 0,176, 0, 0, 0,
+ 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,
+101, 0, 0, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 99,111,
+115, 48, 0, 0, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,115,
+105,110, 48, 0, 0, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+111,114,100,101,114, 0, 0, 0, 0, 0, 25, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0,119,105,100,116,104, 0, 9, 0, 0, 0, 25, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0,104,101,105,103,104,116, 0, 9, 0, 0, 0, 25, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 15, 0, 0,
+ 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0,
+ 0,179, 0, 0, 0, 0, 1, 0, 3, 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0,
+ 1, 94, 0, 0, 0, 30, 0,128, 0, 1, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0,
+ 0, 0, 72,101,105,103,104,116, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0,
+ 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0, 0,
+ 1, 0, 3, 4, 0, 0, 0, 75, 0, 64, 0, 93, 0, 0, 1, 94, 0, 0, 0, 30,
+ 0,128, 0, 1, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 87,105,100,116,
+104, 0, 0, 0, 0, 0, 4, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0,
+ 0, 0,179, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109,
+ 97,103,101, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0, 0, 1, 0, 3, 13, 0, 0, 0,
+ 75, 0, 64, 0, 92,128, 0, 1, 90, 0, 0, 0, 22,192, 0,128, 75, 0, 64, 0,
+ 93, 0, 0, 1, 94, 0, 0, 0, 22,192, 0,128, 75, 0, 64, 0, 92,128, 0, 1,
+ 79, 64,192, 0, 94, 0, 0, 1, 30, 0,128, 0, 2, 0, 0, 0, 4, 7, 0, 0,
+ 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+ 64, 0, 0, 0, 0, 13, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0,
+ 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0,
+ 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212, 0, 0,
+ 0, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0, 0,
+ 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214,
+ 0, 0, 0,227, 0, 0, 0, 0, 1, 0, 8, 36, 0, 0, 0, 75, 0, 64, 0, 92,
+128, 0, 1, 79, 64,192, 0,133,128, 0, 0,134,192, 64, 1,203, 0, 64, 0,220,
+128, 0, 1, 1, 65, 0, 0,156,128,128, 1,154, 0, 0, 0, 22, 0, 0,128, 76,
+ 0,193, 0,133, 64, 1, 0,134,128, 65, 1,192, 0, 0, 0, 3, 1, 0, 2, 64,
+ 1,128, 0,156,128, 0, 2,197, 64, 1, 0,198,128,193, 1, 0, 1, 0, 0, 67,
+ 1,128, 2,139, 1, 64, 0,156,129, 0, 1,143, 65, 64, 3,220,128, 0, 2, 5,
+ 65, 1, 0, 6,193, 65, 2, 64, 1, 0, 0,128, 1, 0, 1,192, 1,128, 1, 28,
+ 65, 0, 2, 0, 1, 0, 1, 64, 1,128, 1, 30, 1,128, 1, 30, 0,128, 0, 8,
+ 0, 0, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 72,101,105,103,104,116, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 64, 4, 5, 0, 0, 0, 0, 0, 0, 0,109, 97,116,
+104, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0,109,111,100, 0, 3, 0, 0, 0, 0,
+ 0, 0,240, 63, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0,
+ 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,
+100, 0, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 73,110,
+116,101,114,108, 97, 99,101, 83,112,108,105,116, 0, 0, 0, 0, 0, 36, 0, 0,
+ 0,216, 0, 0, 0,216, 0, 0, 0,216, 0, 0, 0,217, 0, 0, 0,217, 0, 0,
+ 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0, 0,217, 0, 0,
+ 0,217, 0, 0, 0,218, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,221, 0, 0,
+ 0,221, 0, 0, 0,221, 0, 0, 0,221, 0, 0, 0,222, 0, 0, 0,222, 0, 0,
+ 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0,
+ 0,222, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0,
+ 0,225, 0, 0, 0,225, 0, 0, 0,226, 0, 0, 0,226, 0, 0, 0,226, 0, 0,
+ 0,227, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99,
+ 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0, 0,
+ 0, 0, 0,100,115,116, 95,104,101,105,103,104,116, 49, 0, 3, 0, 0, 0, 35,
+ 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101,
+ 49, 0, 18, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,100,115,
+116, 95,105,109, 97,103,101, 50, 0, 26, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,229, 0, 0, 0,235, 0, 0, 0, 0, 1, 0,
+ 3, 14, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1,133, 64, 0, 0,134,128, 64,
+ 1, 87,128,128, 0, 22,192, 0,128,133, 64, 0, 0,134,192, 64, 1, 23,128,128,
+ 0, 22, 64, 0,128,133, 64, 0, 0, 70, 0, 65, 1, 94, 0, 0, 1, 30, 0,128,
+ 0, 5, 0, 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 68, 97,116, 97, 84,121,
+112,101, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 5, 0, 0, 0,
+ 0, 0, 0, 0, 66, 89, 84, 69, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 85, 83,
+ 72, 79, 82, 84, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 73, 78, 84, 0, 0, 0,
+ 0, 0, 14, 0, 0, 0,230, 0, 0, 0,230, 0, 0, 0,231, 0, 0, 0,231, 0,
+ 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0, 0, 0,231, 0,
+ 0, 0,231, 0, 0, 0,232, 0, 0, 0,232, 0, 0, 0,234, 0, 0, 0,235, 0,
+ 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,105,109, 97,103,101, 0,
+ 0, 0, 0, 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100, 97,116, 97,
+ 95,116,121,112,101, 0, 2, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,247, 0, 0, 0,251, 0, 0, 0, 0, 3, 0, 9, 13, 0,
+ 0, 0,197, 0, 0, 0,198, 64,192, 1, 0, 1, 0, 0,220,128, 0, 1, 5, 1,
+ 0, 0, 6,129, 64, 2, 64, 1, 0, 0,128, 1,128, 0,192, 1,128, 1, 0, 2,
+ 0, 1, 28, 65,128, 2,222, 0, 0, 1, 30, 0,128, 0, 3, 0, 0, 0, 4, 3,
+ 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,
+109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 4, 25, 0, 0,
+ 0, 0, 0, 0, 0, 80,114,111, 99,101,115,115, 65,114,105,116,104,109,101,116,
+105, 99, 67,111,110,115,116, 79,112, 0, 0, 0, 0, 0, 13, 0, 0, 0,248, 0,
+ 0, 0,248, 0, 0, 0,248, 0, 0, 0,248, 0, 0, 0,249, 0, 0, 0,249, 0,
+ 0, 0,249, 0, 0, 0,249, 0, 0, 0,249, 0, 0, 0,249, 0, 0, 0,249, 0,
+ 0, 0,250, 0, 0, 0,251, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 12, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95, 99,111,110,115,116, 0, 0, 0,
+ 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,111,112, 0, 0, 0, 0,
+ 0, 12, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,
+103,101, 0, 4, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 1, 0, 0, 6, 1, 0, 0, 0, 2, 0, 6, 11, 0, 0, 0,133,
+ 0, 0, 0,134, 64, 64, 1,198,128, 64, 0,156,128, 0, 1,197, 0, 0, 0,198,
+192,192, 1, 0, 1, 0, 0, 64, 1, 0, 1,220, 64,128, 1,158, 0, 0, 1, 30,
+ 0,128, 0, 4, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4,
+ 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66,
+ 97,115,101,100, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 20, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 77,117,108,116,105,112,108,101, 77,101,
+ 97,110, 0, 0, 0, 0, 0, 11, 0, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3,
+ 1, 0, 0, 3, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4,
+ 1, 0, 0, 4, 1, 0, 0, 5, 1, 0, 0, 6, 1, 0, 0, 3, 0, 0, 0, 15,
+ 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,
+116, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,
+116, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 4, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 12, 1,
+ 0, 0, 0, 2, 0, 7, 12, 0, 0, 0,133, 0, 0, 0,134, 64, 64, 1,198,128,
+ 64, 0,156,128, 0, 1,197, 0, 0, 0,198,192,192, 1, 0, 1, 0, 0, 64, 1,
+128, 0,128, 1, 0, 1,220, 64, 0, 2,158, 0, 0, 1, 30, 0,128, 0, 4, 0,
+ 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0,
+ 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0,
+ 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 22, 0, 0, 0, 0, 0, 0, 0, 80,114,
+111, 99,101,115,115, 77,117,108,116,105,112,108,101, 83,116,100, 68,101,118, 0,
+ 0, 0, 0, 0, 12, 0, 0, 0, 9, 1, 0, 0, 9, 1, 0, 0, 9, 1, 0, 0,
+ 9, 1, 0, 0, 10, 1, 0, 0, 10, 1, 0, 0, 10, 1, 0, 0, 10, 1, 0, 0,
+ 10, 1, 0, 0, 10, 1, 0, 0, 11, 1, 0, 0, 12, 1, 0, 0, 3, 0, 0, 0,
+ 15, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,
+115,116, 0, 0, 0, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,109,
+101, 97,110, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 11, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101, 0, 4, 0, 0, 0,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 1, 0, 0,
+ 26, 1, 0, 0, 0, 1, 0, 8, 28, 0, 0, 0, 69, 0, 0, 0, 70, 64,192, 0,
+128, 0, 0, 0,195, 0, 0, 2, 69, 1, 0, 0, 70,129,192, 2,133, 1, 0, 0,
+134,193, 64, 3, 92,128, 0, 3,133, 0, 0, 0,134, 64, 64, 1,192, 0, 0, 0,
+ 3, 1,128, 2,133, 1, 0, 0,134, 1, 65, 3,197, 1, 0, 0,198,193,192, 3,
+156,128, 0, 3,197, 0, 0, 0,198, 64,193, 1, 0, 1, 0, 0, 64, 1,128, 0,
+128, 1, 0, 1,220, 64, 0, 2,192, 0,128, 0, 0, 1, 0, 1,222, 0,128, 1,
+ 30, 0,128, 0, 6, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0,
+ 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101,
+ 66, 97,115,101,100, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0,
+ 4, 5, 0, 0, 0, 0, 0, 0, 0, 66, 89, 84, 69, 0, 4, 4, 0, 0, 0, 0,
+ 0, 0, 0, 82, 71, 66, 0, 4, 20, 0, 0, 0, 0, 0, 0, 0, 80,114,111, 99,
+101,115,115, 83,112,108,105,116, 89, 67,104,114,111,109, 97, 0, 0, 0, 0, 0,
+ 28, 0, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0,
+ 22, 1, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0, 22, 1, 0, 0,
+ 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0,
+ 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0,
+ 24, 1, 0, 0, 24, 1, 0, 0, 24, 1, 0, 0, 24, 1, 0, 0, 24, 1, 0, 0,
+ 25, 1, 0, 0, 25, 1, 0, 0, 25, 1, 0, 0, 26, 1, 0, 0, 3, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,115,114, 99, 95,105,109, 97,103,101, 0, 0, 0,
+ 0, 0, 27, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,121, 95,105,109, 97,103,
+101, 0, 9, 0, 0, 0, 27, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 99,104,
+114,111,109, 97, 95,105,109, 97,103,101, 0, 18, 0, 0, 0, 27, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 1, 0, 0, 39, 1, 0, 0, 0,
+ 1, 0, 14, 29, 0, 0, 0, 75, 0, 64, 0, 92,128, 0, 1,138, 0, 0, 0,193,
+ 64, 0, 0, 0, 1,128, 0, 65, 65, 0, 0,224,128, 2,128,197,129, 0, 0,198,
+193,192, 3, 0, 2, 0, 1, 69, 2, 1, 0, 70, 66,193, 4,128, 2, 0, 0,195,
+ 2, 0, 6, 69, 3, 1, 0, 70,131,193, 6, 92, 2,128, 2,220, 65, 0, 0,223,
+192,252,127,197, 0, 1, 0,198,192,193, 1, 0, 1, 0, 0, 64, 1, 0, 1,220,
+ 64,128, 1,197, 0, 2, 0, 0, 1, 0, 1,221, 0, 0, 1,222, 0, 0, 0, 30,
+ 0,128, 0, 9, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 68,101,112,116,
+104, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 6, 0, 0, 0, 0, 0, 0, 0,
+116, 97, 98,108,101, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,105,110,115,101,114,
+116, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0,
+ 0, 0, 0, 73,109, 97,103,101, 67,114,101, 97,116,101, 66, 97,115,101,100, 0,
+ 4, 5, 0, 0, 0, 0, 0, 0, 0, 71, 82, 65, 89, 0, 4, 23, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 83,112,108,105,116, 67,111,109,112,111,
+110,101,110,116,115, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0,117,110,112, 97, 99,
+107, 0, 0, 0, 0, 0, 29, 0, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 33, 1,
+ 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 35, 1,
+ 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1,
+ 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1,
+ 0, 0, 34, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1,
+ 0, 0, 37, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1,
+ 0, 0, 39, 1, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,115,114,
+ 99, 95,105,109, 97,103,101, 0, 0, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0,100,101,112,116,104, 0, 2, 0, 0, 0, 28, 0, 0, 0, 11, 0,
+ 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,103,101,115, 0, 3, 0, 0,
+ 0, 28, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 40,102,111,114, 32,105,110,
+100,101,120, 41, 0, 6, 0, 0, 0, 19, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0,
+ 0, 40,102,111,114, 32,108,105,109,105,116, 41, 0, 6, 0, 0, 0, 19, 0, 0,
+ 0, 11, 0, 0, 0, 0, 0, 0, 0, 40,102,111,114, 32,115,116,101,112, 41, 0,
+ 6, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,105, 0, 7, 0,
+ 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1,
+ 0, 0, 45, 1, 0, 0, 0, 1, 0, 6, 14, 0, 0, 0, 69, 0, 0, 0, 70, 64,
+192, 0,134,128, 64, 0,195, 0, 0, 2, 69, 1, 0, 0, 70,193,192, 2, 92,128,
+128, 2,133, 0, 0, 0,134, 0, 65, 1,192, 0, 0, 0, 0, 1,128, 0,156, 64,
+128, 1, 94, 0, 0, 1, 30, 0,128, 0, 5, 0, 0, 0, 4, 3, 0, 0, 0, 0,
+ 0, 0, 0,105,109, 0, 4, 17, 0, 0, 0, 0, 0, 0, 0, 73,109, 97,103,101,
+ 67,114,101, 97,116,101, 66, 97,115,101,100, 0, 3, 0, 0, 0, 0, 0, 0,240,
+ 63, 4, 4, 0, 0, 0, 0, 0, 0, 0, 82, 71, 66, 0, 4, 23, 0, 0, 0, 0,
+ 0, 0, 0, 80,114,111, 99,101,115,115, 77,101,114,103,101, 67,111,109,112,111,
+110,101,110,116,115, 0, 0, 0, 0, 0, 14, 0, 0, 0, 42, 1, 0, 0, 42, 1,
+ 0, 0, 42, 1, 0, 0, 42, 1, 0, 0, 42, 1, 0, 0, 42, 1, 0, 0, 42, 1,
+ 0, 0, 43, 1, 0, 0, 43, 1, 0, 0, 43, 1, 0, 0, 43, 1, 0, 0, 43, 1,
+ 0, 0, 44, 1, 0, 0, 45, 1, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0,
+ 0, 0,115,114, 99, 95,105,109, 97,103,101, 95,108,105,115,116, 0, 0, 0, 0,
+ 0, 13, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,100,115,116, 95,105,109, 97,
+103,101, 0, 7, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,135, 1, 0, 0, 25,
+ 0, 0, 0, 50, 0, 0, 0, 73, 0, 0, 0, 97, 0, 0, 0,122, 0, 0, 0,130,
+ 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132, 0, 0, 0,132,
+ 0, 0, 0,132, 0, 0, 0,133, 0, 0, 0,133, 0, 0, 0,133, 0, 0, 0,134,
+ 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,135, 0, 0, 0,135, 0, 0, 0,135,
+ 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136,
+ 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,136, 0, 0, 0,137,
+ 0, 0, 0,137, 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138,
+ 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,138, 0, 0, 0,139, 0, 0, 0,139,
+ 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139, 0, 0, 0,139,
+ 0, 0, 0,141, 0, 0, 0,144, 0, 0, 0,141, 0, 0, 0,146, 0, 0, 0,149,
+ 0, 0, 0,146, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,151, 0, 0, 0,152,
+ 0, 0, 0,151, 0, 0, 0,154, 0, 0, 0,160, 0, 0, 0,154, 0, 0, 0,162,
+ 0, 0, 0,162, 0, 0, 0,162, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0,164,
+ 0, 0, 0,172, 0, 0, 0,176, 0, 0, 0,172, 0, 0, 0,178, 0, 0, 0,178,
+ 0, 0, 0,178, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179, 0, 0, 0,179,
+ 0, 0, 0,179, 0, 0, 0,180, 0, 0, 0,180, 0, 0, 0,180, 0, 0, 0,181,
+ 0, 0, 0,181, 0, 0, 0,181, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,182,
+ 0, 0, 0,183, 0, 0, 0,183, 0, 0, 0,183, 0, 0, 0,184, 0, 0, 0,184,
+ 0, 0, 0,184, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,186,
+ 0, 0, 0,186, 0, 0, 0,186, 0, 0, 0,187, 0, 0, 0,187, 0, 0, 0,187,
+ 0, 0, 0,188, 0, 0, 0,188, 0, 0, 0,188, 0, 0, 0,189, 0, 0, 0,189,
+ 0, 0, 0,189, 0, 0, 0,190, 0, 0, 0,190, 0, 0, 0,190, 0, 0, 0,191,
+ 0, 0, 0,191, 0, 0, 0,191, 0, 0, 0,192, 0, 0, 0,192, 0, 0, 0,192,
+ 0, 0, 0,193, 0, 0, 0,193, 0, 0, 0,193, 0, 0, 0,194, 0, 0, 0,194,
+ 0, 0, 0,194, 0, 0, 0,195, 0, 0, 0,195, 0, 0, 0,195, 0, 0, 0,196,
+ 0, 0, 0,196, 0, 0, 0,196, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,197,
+ 0, 0, 0,198, 0, 0, 0,198, 0, 0, 0,198, 0, 0, 0,199, 0, 0, 0,199,
+ 0, 0, 0,199, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,201,
+ 0, 0, 0,201, 0, 0, 0,201, 0, 0, 0,202, 0, 0, 0,202, 0, 0, 0,202,
+ 0, 0, 0,203, 0, 0, 0,203, 0, 0, 0,203, 0, 0, 0,204, 0, 0, 0,204,
+ 0, 0, 0,204, 0, 0, 0,205, 0, 0, 0,205, 0, 0, 0,205, 0, 0, 0,206,
+ 0, 0, 0,206, 0, 0, 0,206, 0, 0, 0,207, 0, 0, 0,207, 0, 0, 0,207,
+ 0, 0, 0,208, 0, 0, 0,208, 0, 0, 0,208, 0, 0, 0,209, 0, 0, 0,209,
+ 0, 0, 0,209, 0, 0, 0,210, 0, 0, 0,210, 0, 0, 0,210, 0, 0, 0,211,
+ 0, 0, 0,211, 0, 0, 0,211, 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,212,
+ 0, 0, 0,212, 0, 0, 0,212, 0, 0, 0,214, 0, 0, 0,227, 0, 0, 0,214,
+ 0, 0, 0,235, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237, 0, 0, 0,237,
+ 0, 0, 0,237, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238, 0, 0, 0,238,
+ 0, 0, 0,238, 0, 0, 0,239, 0, 0, 0,239, 0, 0, 0,239, 0, 0, 0,240,
+ 0, 0, 0,240, 0, 0, 0,240, 0, 0, 0,241, 0, 0, 0,241, 0, 0, 0,241,
+ 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,243, 0, 0, 0,243,
+ 0, 0, 0,243, 0, 0, 0,244, 0, 0, 0,244, 0, 0, 0,244, 0, 0, 0,245,
+ 0, 0, 0,245, 0, 0, 0,245, 0, 0, 0,247, 0, 0, 0,251, 0, 0, 0,247,
+ 0, 0, 0,253, 0, 0, 0,253, 0, 0, 0,253, 0, 0, 0,254, 0, 0, 0,254,
+ 0, 0, 0,254, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 2, 1, 0, 0, 6, 1, 0, 0, 2, 1, 0, 0, 8, 1, 0, 0, 12,
+ 1, 0, 0, 8, 1, 0, 0, 14, 1, 0, 0, 14, 1, 0, 0, 14, 1, 0, 0, 15,
+ 1, 0, 0, 15, 1, 0, 0, 15, 1, 0, 0, 16, 1, 0, 0, 16, 1, 0, 0, 16,
+ 1, 0, 0, 16, 1, 0, 0, 16, 1, 0, 0, 16, 1, 0, 0, 16, 1, 0, 0, 17,
+ 1, 0, 0, 17, 1, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 18, 1, 0, 0, 18,
+ 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 19, 1, 0, 0, 21, 1, 0, 0, 26,
+ 1, 0, 0, 21, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28,
+ 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 29,
+ 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29,
+ 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 31, 1, 0, 0, 39, 1, 0, 0, 31,
+ 1, 0, 0, 41, 1, 0, 0, 45, 1, 0, 0, 41, 1, 0, 0, 47, 1, 0, 0, 47,
+ 1, 0, 0, 47, 1, 0, 0, 47, 1, 0, 0, 47, 1, 0, 0, 47, 1, 0, 0, 48,
+ 1, 0, 0, 48, 1, 0, 0, 48, 1, 0, 0, 49, 1, 0, 0, 49, 1, 0, 0, 49,
+ 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 50, 1, 0, 0, 51, 1, 0, 0, 51,
+ 1, 0, 0, 51, 1, 0, 0, 52, 1, 0, 0, 52, 1, 0, 0, 52, 1, 0, 0, 53,
+ 1, 0, 0, 53, 1, 0, 0, 53, 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0, 54,
+ 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0, 54, 1, 0, 0, 55, 1, 0, 0, 55,
+ 1, 0, 0, 55, 1, 0, 0, 55, 1, 0, 0, 55, 1, 0, 0, 55, 1, 0, 0, 56,
+ 1, 0, 0, 56, 1, 0, 0, 56, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57,
+ 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 57, 1, 0, 0, 58,
+ 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 58, 1, 0, 0, 58,
+ 1, 0, 0, 58, 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0, 59,
+ 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0, 59, 1, 0, 0, 60, 1, 0, 0, 60,
+ 1, 0, 0, 60, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61,
+ 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 61, 1, 0, 0, 62, 1, 0, 0, 62,
+ 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62,
+ 1, 0, 0, 63, 1, 0, 0, 63, 1, 0, 0, 63, 1, 0, 0, 64, 1, 0, 0, 64,
+ 1, 0, 0, 64, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 65, 1, 0, 0, 66,
+ 1, 0, 0, 66, 1, 0, 0, 66, 1, 0, 0, 66, 1, 0, 0, 66, 1, 0, 0, 66,
+ 1, 0, 0, 66, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0, 67,
+ 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0, 67, 1, 0, 0, 68, 1, 0, 0, 68,
+ 1, 0, 0, 68, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69,
+ 1, 0, 0, 7, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 79,110,101, 83,111,
+117,114, 99,101, 79,110,101, 68,101,115,116, 0, 1, 0, 0, 0,134, 1, 0, 0,
+ 18, 0, 0, 0, 0, 0, 0, 0, 84,119,111, 83,111,117,114, 99,101,115, 79,110,
+101, 68,101,115,116, 0, 2, 0, 0, 0,134, 1, 0, 0, 20, 0, 0, 0, 0, 0,
+ 0, 0, 84,104,114,101,101, 83,111,117,114, 99,101,115, 79,110,101, 68,101,115,
+116, 0, 3, 0, 0, 0,134, 1, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 79,110,
+101, 83,111,117,114, 99,101, 84,119,111, 68,101,115,116,115, 0, 4, 0, 0, 0,
+134, 1, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 79,110,101, 83,111,117,114, 99,
+101, 84,104,114,101,101, 68,101,115,116,115, 0, 5, 0, 0, 0,134, 1, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0,104,111,117,103,104, 95,104,101,105,103,104,116,
+ 0, 6, 0, 0, 0,134, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,105,110,116,
+ 95,100, 97,116, 97,116,121,112,101, 0,182, 0, 0, 0,134, 1, 0, 0, 0, 0,
+ 0, 0,
+};
+
+ if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"../obj/imlua_process51/im_process_le64w.lo")==0) lua_pcall(L, 0, 0, 0);
+}
diff --git a/im/src/make_uname b/im/src/make_uname
new file mode 100755
index 0000000..b104eac
--- /dev/null
+++ b/im/src/make_uname
@@ -0,0 +1,13 @@
+# This builds all the libraries of the folder for 1 uname
+
+tecmake $1 $2 $3 $4 $5 $6 $7 $8
+tecmake $1 MF=im_process $2 $3 $4 $5 $6 $7 $8
+tecmake $1 MF=im_jp2 $2 $3 $4 $5 $6 $7 $8
+tecmake $1 MF=im_fftw $2 $3 $4 $5 $6 $7 $8
+
+#tecmake $1 MF=imlua3 $2 $3 $4 $5 $6 $7 $8
+
+tecmake $1 MF=imlua5 $2 $3 $4 $5 $6 $7 $8
+tecmake $1 MF=imlua_process5 $2 $3 $4 $5 $6 $7 $8
+tecmake $1 MF=imlua_jp2 $2 $3 $4 $5 $6 $7 $8
+tecmake $1 MF=imlua_fftw5 $2 $3 $4 $5 $6 $7 $8
diff --git a/im/src/make_uname.bat b/im/src/make_uname.bat
new file mode 100755
index 0000000..0bfcec1
--- /dev/null
+++ b/im/src/make_uname.bat
@@ -0,0 +1,74 @@
+@echo off
+REM This builds all the libraries of the folder for 1 uname
+
+if "%1"=="VCC" goto do-vcc
+if "%1"=="vc-all" goto start-all-vc
+
+call tecmake %1 %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=im_process" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=im_jp2" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=im_avi" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=im_fftw" %2 %3 %4 %5 %6 %7 %8
+
+REM call tecmake %1 "MF=imlua3" %2 %3 %4 %5 %6 %7 %8
+
+call tecmake %1 "MF=imlua5" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=imlua_process5" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=imlua_jp2" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=imlua_avi" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=imlua_fftw5" %2 %3 %4 %5 %6 %7 %8
+
+if "%1"=="vc6" goto vc
+if "%1"=="vc7" goto vc
+if "%1"=="vc8" goto vc
+if "%1"=="vc8_64" goto vc
+if "%1"=="vc9" goto vc
+if "%1"=="vc9_64" goto vc
+if "%1"=="dll" goto vc
+if "%1"=="dll7" goto vc
+if "%1"=="dll8" goto vc
+if "%1"=="dll8_64" goto vc
+if "%1"=="dll9" goto vc
+if "%1"=="dll9_64" goto vc
+if "%1"=="all" goto start-all-vc
+goto end
+
+:vc
+call tecmake %1 "MF=im_wmv" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=imlua_wmv" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=im_capture" %2 %3 %4 %5 %6 %7 %8
+call tecmake %1 "MF=imlua_capture5" %2 %3 %4 %5 %6 %7 %8
+if "%1"=="dll" goto dll
+goto end
+
+:dll
+call tecmake mingw4 "MF=im_capture" mingw4-dll
+call tecmake mingw3 "MF=im_capture" mingw3-dll
+call tecmake bc56 "MF=im_capture" bc56-dll
+REM call tecmake owc1 "MF=im_capture" owc1-dll
+goto end
+
+:start-all-vc
+call make_uname VCC vc6 %2 %3 %4 %5 %6
+call make_uname VCC vc7 %2 %3 %4 %5 %6
+call make_uname VCC vc8 %2 %3 %4 %5 %6
+call make_uname VCC vc8_64 %2 %3 %4 %5 %6
+call make_uname VCC vc9 %2 %3 %4 %5 %6
+call make_uname VCC vc9_64 %2 %3 %4 %5 %6
+call make_uname VCC dll %2 %3 %4 %5 %6
+call make_uname VCC dll7 %2 %3 %4 %5 %6
+call make_uname VCC dll8 %2 %3 %4 %5 %6
+call make_uname VCC dll8_64 %2 %3 %4 %5 %6
+call make_uname VCC dll9 %2 %3 %4 %5 %6
+call make_uname VCC dll9_64 %2 %3 %4 %5 %6
+goto end
+
+:do-vcc
+call tecmake %2 "MF=im_wmv" %3 %4 %5 %6 %7 %8
+call tecmake %2 "MF=imlua_wmv" %3 %4 %5 %6 %7 %8
+call tecmake %2 "MF=im_capture" %3 %4 %5 %6 %7 %8
+call tecmake %2 "MF=imlua_capture5" %3 %4 %5 %6 %7 %8
+if "%2"=="dll" goto dll
+goto end
+
+:end
diff --git a/im/src/old_im.cpp b/im/src/old_im.cpp
new file mode 100755
index 0000000..44a0e1c
--- /dev/null
+++ b/im/src/old_im.cpp
@@ -0,0 +1,440 @@
+/** \file
+ * \brief Old API
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: old_im.cpp,v 1.2 2009/08/19 18:39:43 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+
+#include "old_im.h"
+#include "im.h"
+#include "im_util.h"
+#include "im_counter.h"
+
+long imEncodeColor(unsigned char Red, unsigned char Green, unsigned char Blue)
+{
+ return imColorEncode(Red, Green, Blue);
+}
+
+void imDecodeColor(unsigned char* Red, unsigned char* Green, unsigned char* Blue, long Color)
+{
+ imColorDecode(Red, Green, Blue, Color);
+}
+
+static int FormatNew2Old(const char* new_format, const char* compression)
+{
+ int format;
+
+ if (!imStrEqual(new_format, "BMP"))
+ format = IM_BMP;
+ else if (!imStrEqual(new_format, "GIF"))
+ format = IM_GIF;
+ else if (!imStrEqual(new_format, "PCX"))
+ format = IM_PCX;
+ else if (!imStrEqual(new_format, "RAS"))
+ format = IM_RAS;
+ else if (!imStrEqual(new_format, "SGI"))
+ format = IM_SGI;
+ else if (!imStrEqual(new_format, "JPEG"))
+ format = IM_JPG;
+ else if (!imStrEqual(new_format, "LED"))
+ format = IM_LED;
+ else if (!imStrEqual(new_format, "TIFF"))
+ format = IM_TIF;
+ else if (!imStrEqual(new_format, "TGA"))
+ format = IM_TGA;
+ else
+ return -1;
+
+ if (!imStrEqual(compression, "NONE"))
+ format |= IM_DEFAULT;
+
+ return format;
+}
+
+int imFileFormat(char *filename, int* format)
+{
+ char new_format[10], compression[10];
+ int error, image_count;
+
+ imFile* ifile = imFileOpen(filename, &error);
+ if (!ifile) return error;
+
+ imFileGetInfo(ifile, new_format, compression, &image_count);
+ imFileClose(ifile);
+
+ *format = FormatNew2Old(new_format, compression);
+ if (*format == -1)
+ return IM_ERR_FORMAT;
+
+ return IM_ERR_NONE;
+}
+
+static int ColorMode2Type(int color_mode)
+{
+ switch (imColorModeSpace(color_mode))
+ {
+ case IM_BINARY:
+ case IM_GRAY:
+ case IM_MAP:
+ return IM_MAP;
+ default:
+ return IM_RGB;
+ }
+}
+
+int imImageInfo(char *filename, int *width, int *height, int *type, int *palette_count)
+{
+ int error;
+ imFile* ifile = imFileOpen(filename, &error);
+ if (!ifile) return error;
+
+ int data_type, color_mode;
+ error = imFileReadImageInfo(ifile, 0, width, height, &color_mode, &data_type);
+ if (error)
+ {
+ imFileClose(ifile);
+ return error;
+ }
+
+ *type = ColorMode2Type(color_mode);
+ if (*type == -1)
+ {
+ imFileClose(ifile);
+ return IM_ERR_DATA;
+ }
+
+ if (*type == IM_MAP)
+ {
+ long palette[256];
+ imFileGetPalette(ifile, palette, palette_count);
+ }
+
+ imFileClose(ifile);
+ return IM_ERR_NONE;
+}
+
+static imTiffImageDesc iOldTiffImageDescCB = NULL;
+static imGifTranspIndex iOldGifTranspIndexCB = NULL;
+static imResolutionCallback iOldResolutionCB = NULL;
+static imFileCounterCallback iOldCounterCB = NULL;
+
+static int iOldFileCounter(int counter, void* user_data, const char* name, int progress)
+{
+ (void)counter;
+ if (progress == -1 || progress == 1001) return 1;
+ return !iOldCounterCB((char*)user_data, progress/10, (name[4] == 'R')? 0: 1);
+}
+
+int imRegisterCallback(imCallback cb, int cb_id, int format)
+{
+ if (format == IM_ALL)
+ {
+ switch(cb_id)
+ {
+ case IM_COUNTER_CB:
+ iOldCounterCB = (imFileCounterCallback)cb;
+ return 1;
+ case IM_RESOLUTION_CB:
+ iOldResolutionCB = (imResolutionCallback)cb;
+ return 1;
+ }
+ }
+
+ if (format == IM_GIF && cb_id == IM_GIF_TRANSPARENT_COLOR_CB)
+ {
+ iOldGifTranspIndexCB = (imGifTranspIndex)cb;
+ return 1;
+ }
+
+ if (format == IM_TIF && cb_id == IM_TIF_IMAGE_DESCRIPTION_CB)
+ {
+ iOldTiffImageDescCB = (imTiffImageDesc)cb;
+ return 1;
+ }
+
+ return 0;
+}
+
+static void iConvertMapToRGB(const imbyte* src_map, imbyte* red, imbyte* green, imbyte* blue, int count, const long* palette, const int palette_count)
+{
+ imbyte r[256], g[256], b[256];
+ for (int c = 0; c < palette_count; c++)
+ imColorDecode(&r[c], &g[c], &b[c], palette[c]);
+
+ for (int i = 0; i < count; i++)
+ {
+ int index = *src_map++;
+ *red++ = r[index];
+ *green++ = g[index];
+ *blue++ = b[index];
+ }
+}
+
+int imLoadRGB(char *filename, unsigned char *red, unsigned char *green, unsigned char *blue)
+{
+ int error;
+ imFile* ifile = imFileOpen(filename, &error);
+ if (!ifile) return error;
+
+ int width, height, color_mode, data_type;
+ error = imFileReadImageInfo(ifile, 0, &width, &height, &color_mode, &data_type);
+ if (error)
+ {
+ imFileClose(ifile);
+ return error;
+ }
+
+ if (iOldResolutionCB)
+ {
+ double xres = *(float*)imFileGetAttribute(ifile, "XResolution", NULL, NULL);
+ double yres = *(float*)imFileGetAttribute(ifile, "YResolution", NULL, NULL);
+ int res_unit = *(int*)imFileGetAttribute(ifile, "ResolutionUnit", NULL, NULL);
+ iOldResolutionCB(filename, &xres, &yres, &res_unit);
+ }
+
+ if (iOldTiffImageDescCB)
+ {
+ char* img_desc = (char*)imFileGetAttribute(ifile, "Description", NULL, NULL);
+ iOldTiffImageDescCB(filename, img_desc);
+ }
+
+ if (iOldGifTranspIndexCB)
+ {
+ unsigned char transp_index = *(unsigned char*)imFileGetAttribute(ifile, "TransparencyIndex", NULL, NULL);
+ iOldGifTranspIndexCB(filename, &transp_index);
+ }
+
+ int count = width*height;
+ void* data;
+ if (green != red + count || blue != green + count)
+ data = malloc(imImageDataSize(width, height, IM_RGB, IM_BYTE));
+ else
+ data = red;
+
+ if (!data)
+ {
+ imFileClose(ifile);
+ return IM_ERR_MEM;
+ }
+
+ if (iOldCounterCB)
+ imCounterSetCallback(filename, iOldFileCounter);
+
+ error = imFileReadImageData(ifile, data, 1, 0);
+ if (error)
+ {
+ if (data != red) free(data);
+ imFileClose(ifile);
+ return error;
+ }
+
+ if (imColorModeToBitmap(color_mode) != IM_RGB)
+ {
+ long palette[256];
+ int palette_count;
+ imFileGetPalette(ifile, palette, &palette_count);
+ iConvertMapToRGB((imbyte*)data, red, green, blue, count, palette, palette_count);
+ }
+ else if (data != red)
+ {
+ memcpy(red, data, count);
+ memcpy(green, (unsigned char*)data+count, count);
+ memcpy(blue, (unsigned char*)data+2*count, count);
+ }
+
+ imFileClose(ifile);
+
+ if (data != red) free(data);
+ return IM_ERR_NONE;
+}
+
+int imLoadMap(char *filename, unsigned char *map, long *palette)
+{
+ int error;
+ imFile* ifile = imFileOpen(filename, &error);
+ if (!ifile) return error;
+
+ int width, height, color_mode, data_type;
+ error = imFileReadImageInfo(ifile, 0, &width, &height, &color_mode, &data_type);
+ if (error)
+ {
+ imFileClose(ifile);
+ return error;
+ }
+
+ if (imColorModeSpace(color_mode) != IM_MAP &&
+ imColorModeSpace(color_mode) != IM_GRAY &&
+ imColorModeSpace(color_mode) != IM_BINARY)
+ return IM_ERR_DATA;
+
+ if (iOldResolutionCB)
+ {
+ double xres = *(float*)imFileGetAttribute(ifile, "XResolution", NULL, NULL);
+ double yres = *(float*)imFileGetAttribute(ifile, "YResolution", NULL, NULL);
+ int res_unit = *(int*)imFileGetAttribute(ifile, "ResolutionUnit", NULL, NULL);
+ iOldResolutionCB(filename, &xres, &yres, &res_unit);
+ }
+
+ if (iOldTiffImageDescCB)
+ {
+ char* img_desc = (char*)imFileGetAttribute(ifile, "Description", NULL, NULL);
+ iOldTiffImageDescCB(filename, img_desc);
+ }
+
+ if (iOldGifTranspIndexCB)
+ {
+ unsigned char transp_index = *(unsigned char*)imFileGetAttribute(ifile, "TransparencyIndex", NULL, NULL);
+ iOldGifTranspIndexCB(filename, &transp_index);
+ }
+
+ if (iOldCounterCB)
+ imCounterSetCallback(filename, iOldFileCounter);
+
+ error = imFileReadImageData(ifile, map, 1, 0);
+ if (error)
+ {
+ imFileClose(ifile);
+ return error;
+ }
+
+ int palette_count;
+ imFileGetPalette(ifile, palette, &palette_count);
+
+ imFileClose(ifile);
+
+ return IM_ERR_NONE;
+}
+
+static char* i_format_old2new[] = {"BMP", "PCX", "GIF", "TIFF", "RAS", "SGI", "JPEG", "LED", "TGA"};
+
+int imSaveRGB(int width, int height, int format, unsigned char *red, unsigned char *green, unsigned char *blue, char *filename)
+{
+ int error;
+ char* new_format = i_format_old2new[format & 0x00FF];
+
+ imFile* ifile = imFileNew(filename, new_format, &error);
+ if (!ifile) return error;
+
+ if (format & 0xFF00)
+ imFileSetInfo(ifile, NULL);
+ else
+ imFileSetInfo(ifile, "NONE");
+
+ if (iOldResolutionCB)
+ {
+ double xres, yres;
+ int res_unit;
+ iOldResolutionCB(filename, &xres, &yres, &res_unit);
+ float fxres=(float)xres, fyres=(float)yres;
+ imFileSetAttribute(ifile, "XResolution", IM_FLOAT, 1, (void*)&fxres);
+ imFileSetAttribute(ifile, "YResolution", IM_FLOAT, 1, (void*)&fyres);
+ imFileSetAttribute(ifile, "ResolutionUnit", IM_INT, 1, (void*)&res_unit);
+ }
+
+ if (iOldTiffImageDescCB)
+ {
+ char img_desc[50];
+ iOldTiffImageDescCB(filename, img_desc);
+ imFileSetAttribute(ifile, "Description", IM_BYTE, -1, (void*)img_desc);
+ }
+
+ if (iOldGifTranspIndexCB)
+ {
+ unsigned char transp_index;
+ iOldGifTranspIndexCB(filename, &transp_index);
+ imFileSetAttribute(ifile, "TransparencyIndex", IM_BYTE, 1, (void*)&transp_index);
+ }
+
+ error = imFileWriteImageInfo(ifile, width, height, IM_RGB, IM_BYTE);
+ if (error)
+ {
+ imFileClose(ifile);
+ return error;
+ }
+
+ if (iOldCounterCB)
+ imCounterSetCallback(filename, iOldFileCounter);
+
+ int count = width*height;
+ void* data;
+ if (green != red + count || blue != green + count)
+ data = malloc(imImageDataSize(width, height, IM_RGB, IM_BYTE));
+ else
+ data = red;
+
+ if (!data)
+ {
+ imFileClose(ifile);
+ return IM_ERR_MEM;
+ }
+
+ if (data != red)
+ {
+ memcpy(data, red, count);
+ memcpy((unsigned char*)data+count, green, count);
+ memcpy((unsigned char*)data+2*count, blue, count);
+ }
+
+ error = imFileWriteImageData(ifile, data);
+ imFileClose(ifile);
+ if (data != red) free(data);
+ return error;
+}
+
+int imSaveMap(int width, int height, int format, unsigned char *map, int palette_count, long *palette, char *filename)
+{
+ int error;
+ char* new_format = i_format_old2new[format & 0x00FF];
+ imFile* ifile = imFileNew(filename, new_format, &error);
+ if (!ifile) return error;
+
+ if (format & 0xFF00)
+ imFileSetInfo(ifile, NULL);
+ else
+ imFileSetInfo(ifile, "NONE");
+
+ imFileSetPalette(ifile, palette, palette_count);
+
+ if (iOldResolutionCB)
+ {
+ double xres, yres;
+ int res_unit;
+ iOldResolutionCB(filename, &xres, &yres, &res_unit);
+ float fxres=(float)xres, fyres=(float)yres;
+ imFileSetAttribute(ifile, "XResolution", IM_FLOAT, 1, (void*)&fxres);
+ imFileSetAttribute(ifile, "YResolution", IM_FLOAT, 1, (void*)&fyres);
+ imFileSetAttribute(ifile, "ResolutionUnit", IM_INT, 1, (void*)&res_unit);
+ }
+
+ if (iOldTiffImageDescCB)
+ {
+ char img_desc[50];
+ iOldTiffImageDescCB(filename, img_desc);
+ imFileSetAttribute(ifile, "Description", IM_BYTE, -1, (void*)img_desc);
+ }
+
+ if (iOldGifTranspIndexCB)
+ {
+ unsigned char transp_index;
+ iOldGifTranspIndexCB(filename, &transp_index);
+ imFileSetAttribute(ifile, "TransparencyIndex", IM_BYTE, 1, (void*)&transp_index);
+ }
+
+ error = imFileWriteImageInfo(ifile, width, height, IM_MAP, IM_BYTE);
+ if (error)
+ {
+ imFileClose(ifile);
+ return error;
+ }
+
+ if (iOldCounterCB)
+ imCounterSetCallback(filename, iOldFileCounter);
+
+ error = imFileWriteImageData(ifile, map);
+ imFileClose(ifile);
+ return error;
+}
diff --git a/im/src/old_imcolor.c b/im/src/old_imcolor.c
new file mode 100755
index 0000000..0c6b353
--- /dev/null
+++ b/im/src/old_imcolor.c
@@ -0,0 +1,75 @@
+/** \file
+ * \brief Old resize/stretch functions
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: old_imcolor.c,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include "old_im.h"
+#include "im.h"
+#include "im_util.h"
+#include "im_image.h"
+#include "im_convert.h"
+
+void imRGB2Map(int width, int height,
+ unsigned char *red, unsigned char *green, unsigned char *blue,
+ unsigned char *map, int palette_count, long *palette)
+{
+ imConvertRGB2Map(width, height,
+ red, green, blue,
+ map, palette, &palette_count);
+}
+
+void imMap2RGB(int width, int height, unsigned char *map, int palette_count, long *palette, unsigned char *red, unsigned char *green, unsigned char *blue)
+{
+ int i, count, c, index;
+ unsigned char r[256], g[256], b[256];
+
+ for (c = 0; c < palette_count; c++)
+ imColorDecode(&r[c], &g[c], &b[c], palette[c]);
+
+ count = width*height;
+ for (i = 0; i < count; i++)
+ {
+ index = *map++;
+ *red++ = r[index];
+ *green++ = g[index];
+ *blue++ = b[index];
+ }
+}
+
+void imRGB2Gray(int width, int height, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *map, long *grays)
+{
+ int i, count, c;
+
+ for (c = 0; c < 256; c++)
+ *grays++ = imColorEncode((unsigned char)c, (unsigned char)c, (unsigned char)c);
+
+ count = width*height;
+ for (i = 0; i < count; i++)
+ {
+ *map++ = (unsigned char)((*red++ * 30 + *green++ * 59 + *blue++ * 11) / 100);
+ }
+}
+
+void imMap2Gray(int width, int height, unsigned char *map, int palette_count, long *palette, unsigned char *gray_map, long *grays)
+{
+ int i, count, c;
+ unsigned char cnv_table[256];
+ unsigned char r, g, b;
+
+ for (c = 0; c < 256; c++)
+ *grays++ = imColorEncode((unsigned char)c, (unsigned char)c, (unsigned char)c);
+
+ for (c = 0; c < palette_count; c++)
+ {
+ imColorDecode(&r, &g, &b, palette[c]);
+ cnv_table[c] = (unsigned char)((r * 30 + g * 59 + b * 11) / 100);
+ }
+
+ count = width*height;
+ for (i = 0; i < count; i++)
+ {
+ *gray_map++ = cnv_table[*map++];
+ }
+}
diff --git a/im/src/old_imresize.c b/im/src/old_imresize.c
new file mode 100755
index 0000000..8191037
--- /dev/null
+++ b/im/src/old_imresize.c
@@ -0,0 +1,117 @@
+/** \file
+ * \brief Old resize/stretch functions
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: old_imresize.c,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include "old_im.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <memory.h>
+
+
+/*
+ BILINEAR INTERPOLATION:
+
+ x' = floor(x) f(x' , y') = fll
+ y' = floor(y) f(x' , y'+ 1) = flh
+ f(x'+ 1, y') = fhl
+ t = x - x' f(x'+ 1, y'+ 1) = fhh
+ u = y - y'
+
+ f(x,y) = (1-t) * (1-u) * f(x' , y'),
+ (1-t) * u * f(x' , y'+ 1),
+ t * (1-u) * f(x'+ 1, y'),
+ t * u * f(x'+ 1, y'+ 1)
+
+ f(x,y) = fll + (re-arranging)
+ t * (fhl - fll),
+ u * (flh - fll),
+ u * t * (fhh - flh - fhl + fll)
+
+*/
+
+void imResize(int src_width, int src_height, unsigned char *src_map, int dst_width, int dst_height, unsigned char *dst_map)
+{
+ /* Do bilinear interpolation */
+
+ unsigned char *line_mapl, *line_maph;
+ double t, u, src_x, src_y, factor;
+ int fhh, fll, fhl, flh, xl, yl, xh, yh, x, y;
+
+ int *XL = (int*)malloc(dst_width * sizeof(int));
+ double *T = (double*)malloc(dst_width * sizeof(double));
+
+ factor = (double)(src_width-1) / (double)(dst_width-1);
+ for (x = 0; x < dst_width; x++)
+ {
+ src_x = x * factor;
+ xl = (int)floor(src_x);
+ T[x] = src_x - xl;
+ XL[x] = xl;
+ }
+
+ factor = (double)(src_height-1) / (double)(dst_height-1);
+
+ for (y = 0; y < dst_height; y++)
+ {
+ src_y = y * factor;
+ yl = (int)floor(src_y);
+ yh = (yl == src_height-1)? yl: yl + 1;
+ u = src_y - yl;
+
+ line_mapl = src_map + yl * src_width;
+ line_maph = src_map + yh * src_width;
+
+ for (x = 0; x < dst_width; x++)
+ {
+ xl = XL[x];
+ xh = (xl == src_width-1)? xl: xl + 1;
+ t = T[x];
+
+ fll = line_mapl[xl];
+ fhl = line_mapl[xh];
+ flh = line_maph[xl];
+ fhh = line_maph[xh];
+
+ *(dst_map++) = (unsigned char)(u * t * (fhh - flh - fhl + fll) + t * (fhl - fll) + u * (flh - fll) + fll);
+ }
+ }
+
+ free(XL);
+ free(T);
+}
+
+void imStretch(int src_width, int src_height, unsigned char *src_map, int dst_width, int dst_height, unsigned char *dst_map)
+{
+ int x, y, offset;
+ double factor;
+ unsigned char *line_map;
+ int* XTab = (int*)malloc(dst_width*sizeof(int));
+
+ /* initialize convertion tables to speed up the stretch process */
+ factor = (double)(src_width-1) / (double)(dst_width-1);
+ for(x = 0; x < dst_width; x++)
+ XTab[x] = (int)(factor * x + 0.5);
+
+ factor = (double)(src_height-1) / (double)(dst_height-1);
+
+ line_map = src_map;
+
+ for (y = 0; y < dst_height; y++)
+ {
+ for (x = 0; x < dst_width; x++)
+ {
+ offset = XTab[x];
+ *(dst_map++) = line_map[offset];
+ }
+
+ offset = ((int)(factor * y + 0.5)) * src_width;
+ line_map = src_map + offset;
+ }
+
+ free(XTab);
+}
+
diff --git a/im/src/process/im_analyze.cpp b/im/src/process/im_analyze.cpp
new file mode 100755
index 0000000..6fa9405
--- /dev/null
+++ b/im/src/process/im_analyze.cpp
@@ -0,0 +1,1268 @@
+/** \file
+ * \brief Image Analysis
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_analyze.cpp,v 1.2 2009/09/28 20:19:09 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math.h>
+
+#include "im_process_ana.h"
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+
+#define MAX_COUNT 65536 // maximum number of regions
+
+/* ajust the alias table to be a remap table (final step) */
+static void alias_update(imushort* alias_table, int &region_count)
+{
+ int i, real_count = region_count;
+
+ for (i = 0; i < region_count; i++)
+ {
+ if (alias_table[i])
+ {
+ // search for the first alias
+ imushort prev = alias_table[i];
+ while (alias_table[prev])
+ prev = alias_table[prev];
+
+ alias_table[i] = prev;
+ real_count--; // decrement aliases from the region count
+ }
+ }
+
+ // now all the aliases in the same group point to only one alias
+ // transform the alias table into a remap table
+
+ alias_table[0] = 0;
+ alias_table[1] = 0; // border is mapped to background
+
+ int r = 1;
+ for (i = 2; i < region_count; i++)
+ {
+ if (!alias_table[i])
+ {
+ alias_table[i] = (imushort)r; // only non alias get real values
+ r++;
+ }
+ else
+ alias_table[i] = (imushort)(alias_table[alias_table[i]]);
+ }
+
+ region_count = real_count-2; // remove the regions (background,border) from the count
+}
+
+/* find the smallest region number to be set as alias. */
+static void alias_getmin(imushort* alias_table, imushort region, imushort &min)
+{
+ while (alias_table[region])
+ {
+ if (min > alias_table[region])
+ min = alias_table[region];
+
+ region = alias_table[region];
+ }
+}
+
+/* replace all the aliases of a region by its smallest value. */
+static void alias_setmin(imushort* alias_table, imushort region, imushort min)
+{
+ while (alias_table[region])
+ {
+ imushort next_region = alias_table[region];
+ alias_table[region] = min;
+ region = next_region;
+ }
+
+ if (region != min)
+ alias_table[region] = min;
+}
+
+/* set a region number to be an alias of another */
+static void alias_set(imushort* alias_table, imushort region1, imushort region2)
+{
+ if (region1 == region2)
+ return;
+
+ imushort min = region1<region2? region1: region2;
+
+ alias_getmin(alias_table, region1, min);
+ alias_getmin(alias_table, region2, min);
+
+ if (region1 != min && alias_table[region1] != min)
+ alias_setmin(alias_table, region1, min);
+ if (region2 != min && alias_table[region2] != min)
+ alias_setmin(alias_table, region2, min);
+}
+
+static int DoAnalyzeFindRegions(int width, int height, imbyte* map, imushort* new_map, int connect)
+{
+ int i, j;
+
+ // mark the pixels that touch the border
+ // if a region touch the border, is the invalid region 1
+
+ imbyte* pmap = map;
+ imushort* new_pmap = new_map;
+ for (j = 0; j < width; j++) // first line
+ {
+ if (pmap[j])
+ new_pmap[j] = 1;
+ }
+ pmap += width;
+ new_pmap += width;
+
+ for (i = 1; i < height-1; i++) // first column
+ {
+ if (pmap[0])
+ new_pmap[0] = 1;
+
+ pmap += width;
+ new_pmap += width;
+ }
+
+ // find and connect the regions
+
+ imbyte* pmap1 = map; // previous line (line 0)
+ imushort* new_pmap1 = new_map;
+
+ pmap = map + width; // current line (line 1)
+ new_pmap = new_map + width;
+
+ int region_count = 2; // 0- background, 1-border
+ imushort* alias_table = new imushort [MAX_COUNT];
+ memset(alias_table, 0, MAX_COUNT); // aliases are all zero at start (not used)
+
+ for (i = 1; i < height; i++)
+ {
+ for (j = 1; j < width; j++)
+ {
+ int has_j1 = j < width-1? 1: 0;
+ if (pmap[j])
+ {
+ if (pmap[j-1] || pmap1[j] ||
+ (connect == 8 && (pmap1[j-1] || (has_j1&&pmap1[j+1])))) // 4 or 8 connected to the previous neighbors
+ {
+ imushort region = 0;
+ if (i == height-1 || j == width-1)
+ {
+ region = new_pmap[j] = 1;
+ }
+
+ if (pmap[j-1])
+ {
+ if (!region)
+ region = new_pmap[j-1]; // horizontal neighbor -00
+ else // X1
+ {
+ // this is a right border pixel that connects to an horizontal neighbor
+
+ // this pixel can connect two different regions
+ alias_set(alias_table, region, new_pmap[j-1]);
+ }
+ }
+
+ if (pmap1[j]) // vertical neighbor
+ {
+ if (!region)
+ region = new_pmap1[j]; // isolated vertical neighbor -X-
+ else // 01
+ {
+ // an horizontal neighbor connects to a vertical neighbor -X-
+ // X1
+
+ // this pixel can connect two different regions
+ alias_set(alias_table, region, new_pmap1[j]);
+ }
+ }
+ else if (region && connect==8 && (has_j1&&pmap1[j+1]))
+ {
+ // an horizontal neighbor connects to a right corner neighbor 00X
+ // X1
+
+ // this pixel can connect two different regions
+ alias_set(alias_table, region, new_pmap1[j+1]);
+ }
+
+ if (connect == 8 && (pmap1[j-1] || (has_j1&&pmap1[j+1])) && !region) // isolated corner
+ {
+ // a left corner neighbor or a right corner neighbor X0X
+ // 01
+
+ if (pmap1[j-1]) // left corner
+ region = new_pmap1[j-1];
+
+ if (pmap1[j+1]) // right corner
+ {
+ if (!region) // isolated right corner
+ region = new_pmap1[j+1];
+ else
+ {
+ // this pixel can connect two different regions
+ alias_set(alias_table, new_pmap1[j-1], new_pmap1[j+1]);
+ }
+ }
+ }
+
+ new_pmap[j] = region;
+ }
+ else
+ {
+ // this pixel touches no pixels
+
+ if (i == height-1 || j == width-1)
+ new_pmap[j] = 1;
+ else
+ {
+ // create a new region 000
+ // 01
+ new_pmap[j] = (imushort)region_count;
+ region_count++;
+
+ if (region_count > MAX_COUNT)
+ {
+ delete [] alias_table;
+ return -1;
+ }
+ }
+ }
+ }
+ }
+
+ pmap1 = pmap;
+ new_pmap1 = new_pmap;
+ pmap += width;
+ new_pmap += width;
+ }
+
+ // now all pixels are marked,
+ // but some marks are aliases to others
+
+ // ajust the alias table to be a remap table
+ // and return the real region count
+ alias_update(alias_table, region_count);
+
+ int count = width*height;
+ for (i = 0; i < count; i++)
+ {
+ new_map[i] = alias_table[new_map[i]];
+ }
+
+ delete [] alias_table;
+
+ return region_count;
+}
+
+static int DoAnalyzeFindRegionsBorder(int width, int height, imbyte* map, imushort* new_map, int connect)
+{
+ int i, j;
+
+ imbyte* pmap1 = map - width; // previous line (line -1 = invalid)
+ imushort* new_pmap1 = new_map - width;
+
+ imbyte* pmap = map; // current line (line 0)
+ imushort* new_pmap = new_map;
+
+ int region_count = 2; // still consider: 0- background, 1-border
+ imushort* alias_table = new imushort [MAX_COUNT];
+ memset(alias_table, 0, MAX_COUNT); // aliases are all zero at start (not used)
+
+ for (i = 0; i < height; i++)
+ {
+ for (j = 0; j < width; j++)
+ {
+ if (pmap[j])
+ {
+ int b01 = j > 0? 1: 0; // valid for pmap[j-1]
+ int b10 = i > 0? 1: 0; // valid for pmap1[j]
+ int b11 = i > 0 && j > 0? 1: 0; // valid for pmap1[j-1]
+ int b12 = i > 0 && j < width-1? 1: 0; // valid for pmap1[j+1]
+
+ if ((b01&&pmap[j-1]) || (b10&&pmap1[j]) ||
+ (connect == 8 && ((b11&&pmap1[j-1]) || (b12&&pmap1[j+1])))) // 4 or 8 connected to the previous neighbors
+ {
+ imushort region = 0;
+
+ if (b01&&pmap[j-1])
+ {
+ if (!region)
+ region = new_pmap[j-1]; // horizontal neighbor -00
+ else // X1
+ {
+ // this is a right border pixel that connects to an horizontal neighbor
+
+ // this pixel can connect two different regions
+ alias_set(alias_table, region, new_pmap[j-1]);
+ }
+ }
+
+ if (b10&&pmap1[j]) // vertical neighbor
+ {
+ if (!region)
+ region = new_pmap1[j]; // isolated vertical neighbor -X-
+ else // 01
+ {
+ // an horizontal neighbor connects to a vertical neighbor -X-
+ // X1
+
+ // this pixel can connect two different regions
+ alias_set(alias_table, region, new_pmap1[j]);
+ }
+ }
+ else if (region && connect == 8 && (b12&&pmap1[j+1]))
+ {
+ // an horizontal neighbor connects to a right corner neighbor 00X
+ // X1
+
+ // this pixel can connect two different regions
+ alias_set(alias_table, region, new_pmap1[j+1]);
+ }
+
+ if (connect == 8 && ((b11&&pmap1[j-1]) || (b12&&pmap1[j+1])) && !region) // isolated corner
+ {
+ // a left corner neighbor or a right corner neighbor X0X
+ // 01
+
+ if (b11&&pmap1[j-1]) // left corner
+ region = new_pmap1[j-1];
+
+ if (b12&&pmap1[j+1]) // right corner
+ {
+ if (!region) // isolated right corner
+ region = new_pmap1[j+1];
+ else
+ {
+ // this pixel can connect two different regions
+ alias_set(alias_table, new_pmap1[j-1], new_pmap1[j+1]);
+ }
+ }
+ }
+
+ new_pmap[j] = region;
+ }
+ else
+ {
+ // this pixel touches no pixels
+
+ // create a new region 000
+ // 01
+ new_pmap[j] = (imushort)region_count;
+ region_count++;
+
+ if (region_count > MAX_COUNT)
+ {
+ delete [] alias_table;
+ return -1;
+ }
+ }
+ }
+ }
+
+ pmap1 = pmap;
+ new_pmap1 = new_pmap;
+ pmap += width;
+ new_pmap += width;
+ }
+
+ // now all pixels are marked,
+ // but some marks are aliases to others
+
+ // ajust the alias table to be a remap table
+ // and return the real region count
+ alias_update(alias_table, region_count);
+
+ int count = width*height;
+ for (i = 0; i < count; i++)
+ {
+ new_map[i] = alias_table[new_map[i]];
+ }
+
+ delete [] alias_table;
+
+ return region_count;
+}
+
+int imAnalyzeFindRegions(const imImage* image, imImage* NewImage, int connect, int touch_border)
+{
+ imImageSetAttribute(NewImage, "REGION_CONNECT", IM_BYTE, 1, connect==4?"4":"8");
+ if (touch_border)
+ return DoAnalyzeFindRegionsBorder(image->width, image->height, (imbyte*)image->data[0], (imushort*)NewImage->data[0], connect);
+ else
+ return DoAnalyzeFindRegions(image->width, image->height, (imbyte*)image->data[0], (imushort*)NewImage->data[0], connect);
+}
+
+void imAnalyzeMeasureArea(const imImage* image, int* data_area, int region_count)
+{
+ imushort* img_data = (imushort*)image->data[0];
+
+ memset(data_area, 0, region_count*sizeof(int));
+
+ for (int i = 0; i < image->count; i++)
+ {
+ if (*img_data)
+ data_area[(*img_data) - 1]++;
+ img_data++;
+ }
+}
+
+void imAnalyzeMeasureCentroid(const imImage* image, const int* data_area, int region_count, float* data_cx, float* data_cy)
+{
+ imushort* img_data = (imushort*)image->data[0];
+ int* local_data_area = 0;
+
+ if (!data_area)
+ {
+ local_data_area = (int*)malloc(region_count*sizeof(int));
+ imAnalyzeMeasureArea(image, local_data_area, region_count);
+ data_area = (const int*)local_data_area;
+ }
+
+ if (data_cx) memset(data_cx, 0, region_count*sizeof(float));
+ if (data_cy) memset(data_cy, 0, region_count*sizeof(float));
+
+ for (int y = 0; y < image->height; y++)
+ {
+ int offset = y*image->width;
+
+ for (int x = 0; x < image->width; x++)
+ {
+ int region_index = img_data[offset+x];
+ if (region_index)
+ {
+ if (data_cx) data_cx[region_index-1] += (float)x;
+ if (data_cy) data_cy[region_index-1] += (float)y;
+ }
+ }
+ }
+
+ for (int i = 0; i < region_count; i++)
+ {
+ if (data_cx) data_cx[i] /= (float)data_area[i];
+ if (data_cy) data_cy[i] /= (float)data_area[i];
+ }
+
+ if (local_data_area)
+ free(local_data_area);
+}
+
+static inline double ipow(double x, int j)
+{
+ double r = 1.0;
+ for (int i = 0; i < j; i++)
+ r *= x;
+ return r;
+}
+
+static void iCalcMoment(double* cm, int px, int py, const imImage* image, const float* cx, const float* cy, int region_count)
+{
+ imushort* img_data = (imushort*)image->data[0];
+
+ memset(cm, 0, region_count*sizeof(double));
+
+ for (int y = 0; y < image->height; y++)
+ {
+ int offset = y*image->width;
+
+ for (int x = 0; x < image->width; x++)
+ {
+ int region_index = img_data[offset+x];
+ if (region_index)
+ {
+ int i = region_index-1;
+
+ if (px == 0)
+ cm[i] += ipow(y-cy[i],py);
+ else if (py == 0)
+ cm[i] += ipow(x-cx[i],px);
+ else
+ cm[i] += ipow(x-cx[i],px)*ipow(y-cy[i],py);
+ }
+ }
+ }
+}
+
+template<class T>
+static inline int IsPerimeterPoint(T* map, int width, int height, int x, int y)
+{
+ // map here points to the start of the line, even if its an invalid line.
+
+ // if outside the image, then is not a perimeter line.
+ if (x == -1 || x == width ||
+ y == -1 || y == height)
+ return 0;
+
+ T v = map[x]; // here v is image(x,y)
+ if (!v)
+ return 0;
+
+ // if touches the border, then is a perimeter line.
+ if (x == 0 || x == width-1 ||
+ y == 0 || y == height-1)
+ return 1;
+
+ // if has 4 connected neighbors, then is a perimeter line.
+ if (map[width+x] != v ||
+ map[x+1] != v ||
+ map[x-1] != v ||
+ map[-width+x] != v)
+ return 1;
+
+ return 0;
+}
+
+void imAnalyzeMeasurePrincipalAxis(const imImage* image, const int* data_area, const float* data_cx, const float* data_cy,
+ const int region_count, float* major_slope, float* major_length,
+ float* minor_slope, float* minor_length)
+{
+ int i;
+ int *local_data_area = 0;
+ float *local_data_cx = 0, *local_data_cy = 0;
+
+ if (!data_area)
+ {
+ local_data_area = (int*)malloc(region_count*sizeof(int));
+ imAnalyzeMeasureArea(image, local_data_area, region_count);
+ data_area = (const int*)local_data_area;
+ }
+
+ if (!data_cx || !data_cy)
+ {
+ if (!data_cx)
+ {
+ local_data_cx = (float*)malloc(region_count*sizeof(float));
+ data_cx = (const float*)local_data_cx;
+ }
+
+ if (!data_cy)
+ {
+ local_data_cy = (float*)malloc(region_count*sizeof(float));
+ data_cy = (const float*)local_data_cy;
+ }
+
+ if (local_data_cx && local_data_cy)
+ imAnalyzeMeasureCentroid(image, data_area, region_count, local_data_cx, local_data_cy);
+ else if (local_data_cx)
+ imAnalyzeMeasureCentroid(image, data_area, region_count, local_data_cx, NULL);
+ else if (local_data_cy)
+ imAnalyzeMeasureCentroid(image, data_area, region_count, NULL, local_data_cy);
+ }
+
+ // additional moments
+ double* cm20 = (double*)malloc(region_count*sizeof(double));
+ double* cm02 = (double*)malloc(region_count*sizeof(double));
+ double* cm11 = (double*)malloc(region_count*sizeof(double));
+
+ iCalcMoment(cm20, 2, 0, image, data_cx, data_cy, region_count);
+ iCalcMoment(cm02, 0, 2, image, data_cx, data_cy, region_count);
+ iCalcMoment(cm11, 1, 1, image, data_cx, data_cy, region_count);
+
+ float *local_major_slope = 0, *local_minor_slope = 0;
+ if (!major_slope)
+ {
+ local_major_slope = (float*)malloc(region_count*sizeof(float));
+ major_slope = local_major_slope;
+ }
+ if (!minor_slope)
+ {
+ local_minor_slope = (float*)malloc(region_count*sizeof(float));
+ minor_slope = local_minor_slope;
+ }
+
+#define RAD2DEG 57.296
+
+ // We are going to find 2 axis parameters.
+ // Axis 1 are located in quadrants 1-3
+ // Axis 2 are located in quadrants 2-4
+
+ // Quadrants
+ // 2 | 1
+ // -----
+ // 3 | 4
+
+ // line coeficients for lines that belongs to axis 1 and 2
+ float* A1 = (float*)malloc(region_count*sizeof(float));
+ float* A2 = (float*)malloc(region_count*sizeof(float));
+ float* C1 = (float*)malloc(region_count*sizeof(float));
+ float* C2 = (float*)malloc(region_count*sizeof(float));
+
+ float *slope1 = major_slope; // Use major_slope as a storage place,
+ float *slope2 = minor_slope; // and create an alias to make code clear.
+
+ for (i = 0; i < region_count; i++)
+ {
+ if (cm11[i] == 0)
+ {
+ slope1[i] = 0;
+ slope2[i] = 90;
+
+ // These should not be used
+ A1[i] = 0;
+ A2[i] = 0; // infinite
+ C1[i] = 0; // data_cy[i]
+ C2[i] = 0;
+ }
+ else
+ {
+ double b = (cm20[i] - cm02[i])/cm11[i];
+ double delta = sqrt(b*b + 4.0);
+ double r1 = (-b-delta)/2.0;
+ double r2 = (-b+delta)/2.0;
+ float a1 = (float)(atan(r1)*RAD2DEG + 90); // to avoid negative results
+ float a2 = (float)(atan(r2)*RAD2DEG + 90);
+
+ if (a1 == 180) a1 = 0;
+ if (a2 == 180) a2 = 0;
+
+ if (a1 < 90) // a1 is quadrants q1-q3
+ {
+ slope1[i] = a1;
+ slope2[i] = a2;
+ A1[i] = (float)r1;
+ A2[i] = (float)r2;
+ }
+ else // a2 is quadrants q1-q3
+ {
+ slope1[i] = a2;
+ slope2[i] = a1;
+ A1[i] = (float)r2;
+ A2[i] = (float)r1;
+ }
+
+ C1[i] = data_cy[i] - A1[i] * data_cx[i];
+ C2[i] = data_cy[i] - A2[i] * data_cx[i];
+ }
+ }
+
+ // moments are not necessary anymore
+ free(cm20); free(cm02); free(cm11);
+ cm20 = 0; cm02 = 0; cm11 = 0;
+
+ // maximum distance from a point in the perimeter to an axis in each side of the axis
+ // D1 is distance to axis 1, a and b are sides
+ float* D1a = (float*)malloc(region_count*sizeof(float));
+ float* D1b = (float*)malloc(region_count*sizeof(float));
+ float* D2a = (float*)malloc(region_count*sizeof(float));
+ float* D2b = (float*)malloc(region_count*sizeof(float));
+ memset(D1a, 0, region_count*sizeof(float));
+ memset(D1b, 0, region_count*sizeof(float));
+ memset(D2a, 0, region_count*sizeof(float));
+ memset(D2b, 0, region_count*sizeof(float));
+
+ imushort* img_data = (imushort*)image->data[0];
+ int width = image->width;
+ int height = image->height;
+ for (int y = 0; y < height; y++)
+ {
+ int offset = y*width;
+
+ for (int x = 0; x < width; x++)
+ {
+ if (IsPerimeterPoint(img_data+offset, width, height, x, y))
+ {
+ i = img_data[offset+x] - 1;
+
+ float d1, d2;
+ if (slope2[i] == 90)
+ {
+ d2 = y - data_cy[i]; // I ckecked this many times, looks odd but it is correct.
+ d1 = x - data_cx[i];
+ }
+ else
+ {
+ d1 = A1[i]*x - y + C1[i];
+ d2 = A2[i]*x - y + C2[i];
+ }
+
+ if (d1 < 0)
+ {
+ d1 = (float)fabs(d1);
+ if (d1 > D1a[i])
+ D1a[i] = d1;
+ }
+ else
+ {
+ if (d1 > D1b[i])
+ D1b[i] = d1;
+ }
+
+ if (d2 < 0)
+ {
+ d2 = (float)fabs(d2);
+ if (d2 > D2a[i])
+ D2a[i] = d2;
+ }
+ else
+ {
+ if (d2 > D2b[i])
+ D2b[i] = d2;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < region_count; i++)
+ {
+ float AB1 = (float)sqrt(A1[i]*A1[i] + 1);
+ float AB2 = (float)sqrt(A2[i]*A2[i] + 1);
+
+ float D1 = (D1a[i] + D1b[i]) / AB1;
+ float D2 = (D2a[i] + D2b[i]) / AB2;
+
+ if (D1 < D2) // Major Axis in 2-4 quadrants
+ {
+ // now remember that we did an alias before
+ // slope1 -> major_slope
+ // slope2 -> minor_slope
+
+ float tmp = major_slope[i];
+ major_slope[i] = minor_slope[i];
+ minor_slope[i] = tmp;
+
+ if (minor_length) minor_length[i] = D1;
+ if (major_length) major_length[i] = D2;
+ }
+ else
+ {
+ if (minor_length) minor_length[i] = D2;
+ if (major_length) major_length[i] = D1;
+ }
+ }
+
+ if (local_major_slope) free(local_major_slope);
+ if (local_minor_slope) free(local_minor_slope);
+ if (local_data_area) free(local_data_area);
+ if (local_data_cx) free(local_data_cx);
+ if (local_data_cy) free(local_data_cy);
+
+ free(A1);
+ free(A2);
+ free(C1);
+ free(C2);
+
+ free(D1b);
+ free(D2b);
+ free(D1a);
+ free(D2a);
+}
+
+void imAnalyzeMeasureHoles(const imImage* image, int connect, int* count_data, int* area_data, float* perim_data)
+{
+ int i;
+ imImage *inv_image = imImageCreate(image->width, image->height, IM_BINARY, IM_BYTE);
+ imbyte* inv_data = (imbyte*)inv_image->data[0];
+ imushort* img_data = (imushort*)image->data[0];
+
+ // finds the holes in the inverted image
+ for (i = 0; i < image->count; i++)
+ {
+ if (*img_data)
+ *inv_data = 0;
+ else
+ *inv_data = 1;
+
+ img_data++;
+ inv_data++;
+ }
+
+ imImage *holes_image = imImageClone(image);
+ if (!holes_image)
+ return;
+
+ int holes_count = imAnalyzeFindRegions(inv_image, holes_image, connect, 0);
+ imImageDestroy(inv_image);
+
+ if (!holes_count)
+ {
+ imImageDestroy(holes_image);
+ return;
+ }
+
+ // measure the holes area
+ int* holes_area = (int*)malloc(holes_count*sizeof(int));
+ imAnalyzeMeasureArea(holes_image, holes_area, holes_count);
+
+ float* holes_perim = 0;
+ if (perim_data)
+ {
+ holes_perim = (float*)malloc(holes_count*sizeof(int));
+ imAnalyzeMeasurePerimeter(holes_image, holes_perim, holes_count);
+ }
+
+ imushort* holes_data = (imushort*)holes_image->data[0];
+ img_data = (imushort*)image->data[0];
+
+ // holes do not touch the border
+ for (int y = 1; y < image->height-1; y++)
+ {
+ int offset_up = (y+1)*image->width;
+ int offset = y*image->width;
+ int offset_dw = (y-1)*image->width;
+
+ for (int x = 1; x < image->width-1; x++)
+ {
+ int hole_index = holes_data[offset+x];
+
+ if (hole_index && holes_area[hole_index-1]) // a hole not yet used
+ {
+ // if the hole has not been used,
+ // it is the first time we encounter a pixel of this hole.
+ // then it is a pixel from the hole border.
+ // now find which region this hole is inside.
+ // a 4 connected neighbour is necessarilly a valid region or 0.
+
+ int region_index = 0;
+ if (img_data[offset_up + x]) region_index = img_data[offset_up + x];
+ else if (img_data[offset + x+1]) region_index = img_data[offset + x+1];
+ else if (img_data[offset + x-1]) region_index = img_data[offset + x-1];
+ else if (img_data[offset_dw+x]) region_index = img_data[offset_dw+x];
+
+ if (!region_index) continue;
+
+ if (count_data) count_data[region_index-1]++;
+ if (area_data) area_data[region_index-1] += holes_area[hole_index-1];
+ if (perim_data) perim_data[region_index-1] += holes_perim[hole_index-1];
+ holes_area[hole_index-1] = 0; // mark hole as used
+ }
+ }
+ }
+
+ if (holes_perim) free(holes_perim);
+ free(holes_area);
+ imImageDestroy(holes_image);
+}
+
+template<class T>
+static void DoPerimeterLine(T* map, T* new_map, int width, int height)
+{
+ int x, y, offset;
+
+ for (y = 0; y < height; y++)
+ {
+ offset = y*width;
+
+ for (x = 0; x < width; x++)
+ {
+ if (IsPerimeterPoint(map+offset, width, height, x, y))
+ new_map[offset+x] = map[offset+x];
+ else
+ new_map[offset+x] = 0;
+ }
+ }
+}
+
+void imProcessPerimeterLine(const imImage* src_image, imImage* dst_image)
+{
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ DoPerimeterLine((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], src_image->width, src_image->height);
+ break;
+ case IM_USHORT:
+ DoPerimeterLine((imushort*)src_image->data[0], (imushort*)dst_image->data[0], src_image->width, src_image->height);
+ break;
+ case IM_INT:
+ DoPerimeterLine((int*)src_image->data[0], (int*)dst_image->data[0], src_image->width, src_image->height);
+ break;
+ }
+}
+
+/* Perimeter Templates idea based in
+ Parker, Pratical Computer Vision Using C
+
+For 1.414 (sqrt(2)/2 + sqrt(2)/2) [1]:
+ 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 1
+ 0 x 0 0 x 0 0 x 0 0 x 0 0 x 0 0 x 0
+ 0 0 1 1 0 0 1 0 0 0 0 1 1 0 1 0 0 0
+ 129 36 132 33 5 160
+
+For 1.207 (sqrt(2)/2 + 1.0/2) [2]:
+ 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0
+ 1 x 0 1 x 0 0 x 0 0 x 0 0 x 0 0 x 0 0 x 1 0 x 1
+ 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0
+ 17 48 68 65 130 34 12 136
+
+ 0 0 0 1 0 0 1 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0
+ 1 x 0 1 x 0 0 x 0 0 x 0 0 x 1 0 x 1 0 x 0 0 x 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0
+ 20 144 192 96 40 9 3 6
+
+For 1.0 (1.0/2 + 1.0/2) [0]:
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0
+ 1 x 1 0 x 0 1 x 0 0 x 1 1 x 0 0 x 1
+ 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0
+ 24 66 18 10 80 72
+
+For 0.707 (sqrt(2)/2) [3]:
+ 1 0 0 0 0 1 0 0 0 0 0 0
+ 0 x 0 0 x 0 0 x 0 0 x 0 (For Line Length)
+ 0 0 0 0 0 0 0 0 1 1 0 0
+ 128 32 1 4
+
+For 0.5 (1.0/2) [4]:
+ 0 1 0 0 0 0 0 0 0 0 0 0
+ 0 x 0 0 x 1 0 x 0 1 x 0 (For Line Length)
+ 0 0 0 0 0 0 0 1 0 0 0 0
+ 64 8 2 16
+
+*/
+static void iInitPerimTemplate(imbyte *templ, float *v)
+{
+ memset(templ, 0, 256);
+
+ templ[129] = 1;
+ templ[36] = 1;
+ templ[132] = 1;
+ templ[33] = 1;
+ templ[5] = 1;
+ templ[160] = 1;
+
+ templ[17] = 2;
+ templ[48] = 2;
+ templ[68] = 2;
+ templ[65] = 2;
+ templ[130] = 2;
+ templ[34] = 2;
+ templ[12] = 2;
+ templ[136] = 2;
+ templ[20] = 2;
+ templ[144] = 2;
+ templ[192] = 2;
+ templ[96] = 2;
+ templ[40] = 2;
+ templ[9] = 2;
+ templ[3] = 2;
+ templ[6] = 2;
+
+ templ[24] = 0;
+ templ[66] = 0;
+ templ[18] = 0;
+ templ[10] = 0;
+ templ[80] = 0;
+ templ[72] = 0;
+
+ templ[128] = 3;
+ templ[32] = 3;
+ templ[1] = 3;
+ templ[4] = 3;
+
+ templ[64] = 4;
+ templ[8] = 4;
+ templ[2] = 4;
+ templ[16] = 4;
+
+const float DT_SQRT2 = 1.414213562373f;
+const float DT_SQRT2D2 = 0.707106781187f;
+
+ v[1] = DT_SQRT2;
+ v[2] = DT_SQRT2D2 + 0.5f;
+ v[0] = 1.0f;
+ v[3] = DT_SQRT2D2;
+ v[4] = 0.5f;
+}
+
+void imAnalyzeMeasurePerimeter(const imImage* image, float* perim_data, int region_count)
+{
+ static imbyte templ[256];
+ static float vt[5];
+ static int first = 1;
+ if (first)
+ {
+ iInitPerimTemplate(templ, vt);
+ first = 0;
+ }
+
+ imushort* map = (imushort*)image->data[0];
+
+ memset(perim_data, 0, region_count*sizeof(int));
+
+ int width = image->width;
+ int height = image->height;
+ for (int y = 0; y < height; y++)
+ {
+ int offset = y*image->width;
+
+ for (int x = 0; x < width; x++)
+ {
+ if (IsPerimeterPoint(map+offset, width, height, x, y))
+ {
+ int T = 0;
+
+ // check the 8 neighboors if they belong to the perimeter
+ if (IsPerimeterPoint(map+offset+width, width, height, x-1, y+1))
+ T |= 0x01;
+ if (IsPerimeterPoint(map+offset+width, width, height, x, y+1))
+ T |= 0x02;
+ if (IsPerimeterPoint(map+offset+width, width, height, x+1, y+1))
+ T |= 0x04;
+
+ if (IsPerimeterPoint(map+offset, width, height, x-1, y))
+ T |= 0x08;
+ if (IsPerimeterPoint(map+offset, width, height, x+1, y))
+ T |= 0x10;
+
+ if (IsPerimeterPoint(map+offset-width, width, height, x-1, y-1))
+ T |= 0x20;
+ if (IsPerimeterPoint(map+offset-width, width, height, x, y-1))
+ T |= 0x40;
+ if (IsPerimeterPoint(map+offset-width, width, height, x+1, y-1))
+ T |= 0x80;
+
+ if (T)
+ perim_data[map[offset+x] - 1] += vt[templ[T]];
+ }
+ }
+ }
+}
+
+/* Perimeter Area Templates
+
+For "1.0" (0):
+
+ 1 1 1
+ 1 x 1
+ 1 1 1
+ 255
+
+For "0.75" (1):
+
+ 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1
+ 1 x 1 1 x 1 1 x 1 1 x 1 0 x 1 1 x 0 1 x 1 1 x 1
+ 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
+ 251 254 127 223 239 247 253 191
+
+For "0.625" (2):
+
+ 1 1 1 0 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0
+ 1 x 1 1 x 1 0 x 1 1 x 0 0 x 1 1 x 0 1 x 1 1 x 1
+ 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 0 0 1 1 1
+ 249 63 111 215 235 246 252 159
+
+For "0.5" (3):
+
+ 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 1 1 1
+ 1 x 1 0 x 1 1 x 1 1 x 0 0 x 1 0 x 1 1 x 0 1 x 0
+ 1 1 1 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0
+ 31 107 248 214 233 47 151 244
+
+For "0.375" (4):
+
+ 0 0 0 1 1 1 1 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 1 1
+ 1 x 0 1 x 0 1 x 0 0 x 1 1 x 0 0 x 1 0 x 1 0 x 1
+ 1 1 1 0 0 0 1 0 0 0 0 1 1 1 0 0 1 1 1 1 1 0 0 0
+ 23 240 212 105 150 43 15 232
+
+For "0.25" (5):
+
+ 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 1 1
+ 1 x 0 0 x 1 1 x 0 0 x 1 1 x 0 0 x 1 0 x 0 0 x 0
+ 1 1 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0
+ 22 11 208 104 148 41 7 224
+
+For "0.125" (6):
+
+ 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1
+ 1 x 0 0 x 0 0 x 0 0 x 1 1 x 0 0 x 1 0 x 0 0 x 0
+ 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0
+ 20 3 192 40 144 9 6 96
+
+*/
+static void iInitPerimAreaTemplate(imbyte *templ, float *v)
+{
+ memset(templ, 0, 256);
+
+ templ[255] = 0;
+
+ templ[251] = 1;
+ templ[254] = 1;
+ templ[127] = 1;
+ templ[223] = 1;
+ templ[239] = 1;
+ templ[247] = 1;
+ templ[253] = 1;
+ templ[191] = 1;
+
+ templ[249] = 2;
+ templ[63] = 2;
+ templ[111] = 2;
+ templ[215] = 2;
+ templ[235] = 2;
+ templ[246] = 2;
+ templ[252] = 2;
+ templ[159] = 2;
+
+ templ[31] = 3;
+ templ[107] = 3;
+ templ[248] = 3;
+ templ[214] = 3;
+ templ[233] = 3;
+ templ[47] = 3;
+ templ[151] = 3;
+ templ[244] = 3;
+
+ templ[23] = 4;
+ templ[240] = 4;
+ templ[212] = 4;
+ templ[105] = 4;
+ templ[150] = 4;
+ templ[43] = 4;
+ templ[15] = 4;
+ templ[232] = 4;
+
+ templ[22] = 5;
+ templ[11] = 5;
+ templ[208] = 5;
+ templ[104] = 5;
+ templ[148] = 5;
+ templ[41] = 5;
+ templ[7] = 5;
+ templ[224] = 5;
+
+ templ[20] = 6;
+ templ[3] = 6;
+ templ[192] = 6;
+ templ[40] = 6;
+ templ[144] = 6;
+ templ[9] = 6;
+ templ[6] = 6;
+ templ[96] = 6;
+
+ v[0] = 1.0f;
+ v[1] = 0.75f;
+ v[2] = 0.625f;
+ v[3] = 0.5f;
+ v[4] = 0.375f;
+ v[5] = 0.25f;
+ v[6] = 0.125f;
+}
+
+void imAnalyzeMeasurePerimArea(const imImage* image, float* area_data)
+{
+ static imbyte templ[256];
+ static float vt[7];
+ static int first = 1;
+ if (first)
+ {
+ iInitPerimAreaTemplate(templ, vt);
+ first = 0;
+ }
+
+ imushort* map = (imushort*)image->data[0];
+
+ int width = image->width;
+ int height = image->height;
+ for (int y = 0; y < height; y++)
+ {
+ int offset_up = (y+1)*width;
+ int offset = y*width;
+ int offset_dw = (y-1)*width;
+
+ for (int x = 0; x < width; x++)
+ {
+ imushort v = map[offset+x];
+ if (v)
+ {
+ int T = 0;
+ if (x>0 && y<height-1 && map[offset_up + x-1] == v) T |= 0x01;
+ if (y<height-1 && map[offset_up + x ] == v) T |= 0x02;
+ if (x<width-1 && y<height-1 && map[offset_up + x+1] == v) T |= 0x04;
+ if (x>0 && map[offset + x-1] == v) T |= 0x08;
+ if (x<width-1 && map[offset + x+1] == v) T |= 0x10;
+ if (x>0 && y>0 && map[offset_dw + x-1] == v) T |= 0x20;
+ if (y>0 && map[offset_dw + x ] == v) T |= 0x40;
+ if (x<width-1 && y>0 && map[offset_dw + x+1] == v) T |= 0x80;
+
+ if (T)
+ area_data[v-1] += vt[templ[T]];
+ }
+ }
+ }
+}
+
+void imProcessRemoveByArea(const imImage* image, imImage* NewImage, int connect, int start_size, int end_size, int inside)
+{
+ imImage *region_image = imImageCreate(image->width, image->height, IM_GRAY, IM_USHORT);
+ if (!region_image)
+ return;
+
+ int region_count = imAnalyzeFindRegions(image, region_image, connect, 1);
+ if (!region_count)
+ {
+ imImageClear(NewImage);
+ imImageDestroy(region_image);
+ return;
+ }
+
+ if (end_size == 0)
+ end_size = image->width*image->height;
+
+ int outside=0;
+ if (!inside) outside = 1;
+
+ int* area_data = (int*)malloc(region_count*sizeof(int));
+ imAnalyzeMeasureArea(region_image, area_data, region_count);
+
+ imushort* region_data = (imushort*)region_image->data[0];
+ imbyte* img_data = (imbyte*)NewImage->data[0];
+
+ for (int i = 0; i < image->count; i++)
+ {
+ if (*region_data)
+ {
+ int area = area_data[(*region_data) - 1];
+ if (area < start_size || area > end_size)
+ *img_data = (imbyte)outside;
+ else
+ *img_data = (imbyte)inside;
+ }
+ else
+ *img_data = 0;
+
+ region_data++;
+ img_data++;
+ }
+
+ free(area_data);
+ imImageDestroy(region_image);
+}
+
+void imProcessFillHoles(const imImage* image, imImage* NewImage, int connect)
+{
+ // finding regions in the inverted image will isolate only the holes.
+ imProcessNegative(image, NewImage);
+
+ imImage *region_image = imImageCreate(image->width, image->height, IM_GRAY, IM_USHORT);
+ if (!region_image)
+ return;
+
+ int holes_count = imAnalyzeFindRegions(NewImage, region_image, connect, 0);
+ if (!holes_count)
+ {
+ imImageCopy(image, NewImage);
+ imImageDestroy(region_image);
+ return;
+ }
+
+ imushort* region_data = (imushort*)region_image->data[0];
+ imbyte* dst_data = (imbyte*)NewImage->data[0];
+
+ for (int i = 0; i < image->count; i++)
+ {
+ if (*region_data)
+ *dst_data = 1;
+ else
+ *dst_data = !(*dst_data); // Fix negative data.
+
+ region_data++;
+ dst_data++;
+ }
+
+ imImageDestroy(region_image);
+}
diff --git a/im/src/process/im_arithmetic_bin.cpp b/im/src/process/im_arithmetic_bin.cpp
new file mode 100755
index 0000000..494b6c0
--- /dev/null
+++ b/im/src/process/im_arithmetic_bin.cpp
@@ -0,0 +1,587 @@
+/** \file
+ * \brief Binary Arithmetic Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_arithmetic_bin.cpp,v 1.2 2009/10/01 02:56:58 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math.h>
+#include <im_complex.h>
+#include <im_counter.h>
+
+#include "im_process_pon.h"
+#include "im_math_op.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+
+template <class T1, class T2, class T3>
+static void DoBinaryOp(T1 *map1, T2 *map2, T3 *map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_BIN_ADD:
+ for (i = 0; i < count; i++)
+ map[i] = add_op((T3)map1[i], (T3)map2[i]);
+ break;
+ case IM_BIN_SUB:
+ for (i = 0; i < count; i++)
+ map[i] = sub_op((T3)map1[i], (T3)map2[i]);
+ break;
+ case IM_BIN_MUL:
+ for (i = 0; i < count; i++)
+ map[i] = mul_op((T3)map1[i], (T3)map2[i]);
+ break;
+ case IM_BIN_DIV:
+ for (i = 0; i < count; i++)
+ map[i] = div_op((T3)map1[i], (T3)map2[i]);
+ break;
+ case IM_BIN_DIFF:
+ for (i = 0; i < count; i++)
+ map[i] = diff_op((T3)map1[i], (T3)map2[i]);
+ break;
+ case IM_BIN_MIN:
+ for (i = 0; i < count; i++)
+ map[i] = min_op((T3)map1[i], (T3)map2[i]);
+ break;
+ case IM_BIN_MAX:
+ for (i = 0; i < count; i++)
+ map[i] = max_op((T3)map1[i], (T3)map2[i]);
+ break;
+ case IM_BIN_POW:
+ for (i = 0; i < count; i++)
+ map[i] = pow_op((T3)map1[i], (T3)map2[i]);
+ break;
+ }
+}
+
+static void DoBinaryOpByte(imbyte *map1, imbyte *map2, imbyte *map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_BIN_ADD:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(add_op((int)map1[i], (int)map2[i]));
+ break;
+ case IM_BIN_SUB:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(sub_op((int)map1[i], (int)map2[i]));
+ break;
+ case IM_BIN_MUL:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(mul_op((int)map1[i], (int)map2[i]));
+ break;
+ case IM_BIN_DIV:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(div_op((int)map1[i], (int)map2[i]));
+ break;
+ case IM_BIN_DIFF:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(diff_op((int)map1[i], (int)map2[i]));
+ break;
+ case IM_BIN_MIN:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(min_op((int)map1[i], (int)map2[i]));
+ break;
+ case IM_BIN_MAX:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(max_op((int)map1[i], (int)map2[i]));
+ break;
+ case IM_BIN_POW:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(pow_op((int)map1[i], (int)map2[i]));
+ break;
+ }
+}
+
+static void DoBinaryOpCpxReal(imcfloat *map1, float *map2, imcfloat *map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_BIN_ADD:
+ for (i = 0; i < count; i++)
+ map[i] = add_op(map1[i], map2[i]);
+ break;
+ case IM_BIN_SUB:
+ for (i = 0; i < count; i++)
+ map[i] = sub_op(map1[i], map2[i]);
+ break;
+ case IM_BIN_MUL:
+ for (i = 0; i < count; i++)
+ map[i] = mul_op(map1[i], map2[i]);
+ break;
+ case IM_BIN_DIV:
+ for (i = 0; i < count; i++)
+ map[i] = div_op(map1[i], (imcfloat)map2[i]);
+ break;
+ case IM_BIN_DIFF:
+ for (i = 0; i < count; i++)
+ map[i] = diff_op(map1[i], map2[i]);
+ break;
+ case IM_BIN_MIN:
+ for (i = 0; i < count; i++)
+ map[i] = min_op(map1[i], map2[i]);
+ break;
+ case IM_BIN_MAX:
+ for (i = 0; i < count; i++)
+ map[i] = max_op(map1[i], map2[i]);
+ break;
+ case IM_BIN_POW:
+ for (i = 0; i < count; i++)
+ map[i] = pow_op(map1[i], map2[i]);
+ break;
+ }
+}
+
+void imProcessArithmeticOp(const imImage* src_image1, const imImage* src_image2, imImage* dst_image, int op)
+{
+ int count = src_image1->count;
+
+ for (int i = 0; i < src_image1->depth; i++)
+ {
+ switch(src_image1->data_type)
+ {
+ case IM_BYTE:
+ if (dst_image->data_type == IM_FLOAT)
+ DoBinaryOp((imbyte*)src_image1->data[i], (imbyte*)src_image2->data[i], (float*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_USHORT)
+ DoBinaryOp((imbyte*)src_image1->data[i], (imbyte*)src_image2->data[i], (imushort*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_INT)
+ DoBinaryOp((imbyte*)src_image1->data[i], (imbyte*)src_image2->data[i], (int*)dst_image->data[i], count, op);
+ else
+ DoBinaryOpByte((imbyte*)src_image1->data[i], (imbyte*)src_image2->data[i], (imbyte*)dst_image->data[i], count, op);
+ break;
+ case IM_USHORT:
+ if (dst_image->data_type == IM_FLOAT)
+ DoBinaryOp((imushort*)src_image1->data[i], (imushort*)src_image2->data[i], (float*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_INT)
+ DoBinaryOp((imushort*)src_image1->data[i], (imushort*)src_image2->data[i], (int*)dst_image->data[i], count, op);
+ else
+ DoBinaryOp((imushort*)src_image1->data[i], (imushort*)src_image2->data[i], (imushort*)dst_image->data[i], count, op);
+ break;
+ case IM_INT:
+ if (dst_image->data_type == IM_FLOAT)
+ DoBinaryOp((int*)src_image1->data[i], (int*)src_image2->data[i], (float*)dst_image->data[i], count, op);
+ else
+ DoBinaryOp((int*)src_image1->data[i], (int*)src_image2->data[i], (int*)dst_image->data[i], count, op);
+ break;
+ case IM_FLOAT:
+ DoBinaryOp((float*)src_image1->data[i], (float*)src_image2->data[i], (float*)dst_image->data[i], count, op);
+ break;
+ case IM_CFLOAT:
+ if (src_image2->data_type == IM_FLOAT)
+ DoBinaryOpCpxReal((imcfloat*)src_image1->data[i], (float*)src_image2->data[i], (imcfloat*)dst_image->data[i], count, op);
+ else
+ DoBinaryOp((imcfloat*)src_image1->data[i], (imcfloat*)src_image2->data[i], (imcfloat*)dst_image->data[i], count, op);
+ break;
+ }
+ }
+}
+
+template <class T>
+static inline T blend_op(const T& v1, const T& v2, const float& alpha)
+{
+ return (T)(alpha*v1 + (1.0f - alpha)*v2);
+}
+
+template <class T>
+static void DoBlendConst(T *map1, T *map2, T *map, int count, float alpha)
+{
+ for (int i = 0; i < count; i++)
+ map[i] = blend_op(map1[i], map2[i], alpha);
+}
+
+void imProcessBlendConst(const imImage* src_image1, const imImage* src_image2, imImage* dst_image, float alpha)
+{
+ int count = src_image1->count;
+
+ for (int i = 0; i < src_image1->depth; i++)
+ {
+ switch(src_image1->data_type)
+ {
+ case IM_BYTE:
+ DoBlendConst((imbyte*)src_image1->data[i], (imbyte*)src_image2->data[i], (imbyte*)dst_image->data[i], count, alpha);
+ break;
+ case IM_USHORT:
+ DoBlendConst((imushort*)src_image1->data[i], (imushort*)src_image2->data[i], (imushort*)dst_image->data[i], count, alpha);
+ break;
+ case IM_INT:
+ DoBlendConst((int*)src_image1->data[i], (int*)src_image2->data[i], (int*)dst_image->data[i], count, alpha);
+ break;
+ case IM_FLOAT:
+ DoBlendConst((float*)src_image1->data[i], (float*)src_image2->data[i], (float*)dst_image->data[i], count, alpha);
+ break;
+ case IM_CFLOAT:
+ DoBlendConst((imcfloat*)src_image1->data[i], (imcfloat*)src_image2->data[i], (imcfloat*)dst_image->data[i], count, alpha);
+ break;
+ }
+ }
+}
+
+template <class T, class TA>
+static void DoBlend(T *map1, T *map2, TA *alpha, T *map, int count, TA max)
+{
+ for (int i = 0; i < count; i++)
+ map[i] = blend_op(map1[i], map2[i], ((float)alpha[i])/max);
+}
+
+void imProcessBlend(const imImage* src_image1, const imImage* src_image2, const imImage* alpha, imImage* dst_image)
+{
+ int count = src_image1->count;
+
+ for (int i = 0; i < src_image1->depth; i++)
+ {
+ switch(src_image1->data_type)
+ {
+ case IM_BYTE:
+ DoBlend((imbyte*)src_image1->data[i], (imbyte*)src_image2->data[i], (imbyte*)alpha->data[0], (imbyte*)dst_image->data[i], count, (imbyte)255);
+ break;
+ case IM_USHORT:
+ DoBlend((imushort*)src_image1->data[i], (imushort*)src_image2->data[i], (imushort*)alpha->data[0], (imushort*)dst_image->data[i], count, (imushort)65535);
+ break;
+ case IM_INT:
+ DoBlend((int*)src_image1->data[i], (int*)src_image2->data[i], (int*)alpha->data[0], (int*)dst_image->data[i], count, (int)2147483647);
+ break;
+ case IM_FLOAT:
+ DoBlend((float*)src_image1->data[i], (float*)src_image2->data[i], (float*)alpha->data[0], (float*)dst_image->data[i], count, 1.0f);
+ break;
+ case IM_CFLOAT:
+ DoBlend((imcfloat*)src_image1->data[i], (imcfloat*)src_image2->data[i], (float*)alpha->data[0], (imcfloat*)dst_image->data[i], count, 1.0f);
+ break;
+ }
+ }
+}
+
+static void DoBinaryConstOpCpxReal(imcfloat *map1, float value, imcfloat *map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_BIN_ADD:
+ for (i = 0; i < count; i++)
+ map[i] = add_op(map1[i], value);
+ break;
+ case IM_BIN_SUB:
+ for (i = 0; i < count; i++)
+ map[i] = sub_op(map1[i], value);
+ break;
+ case IM_BIN_MUL:
+ for (i = 0; i < count; i++)
+ map[i] = mul_op(map1[i], value);
+ break;
+ case IM_BIN_DIV:
+ for (i = 0; i < count; i++)
+ map[i] = div_op(map1[i], (imcfloat)value);
+ break;
+ case IM_BIN_DIFF:
+ for (i = 0; i < count; i++)
+ map[i] = diff_op(map1[i], value);
+ break;
+ case IM_BIN_MIN:
+ for (i = 0; i < count; i++)
+ map[i] = min_op(map1[i], value);
+ break;
+ case IM_BIN_MAX:
+ for (i = 0; i < count; i++)
+ map[i] = max_op(map1[i], value);
+ break;
+ case IM_BIN_POW:
+ for (i = 0; i < count; i++)
+ map[i] = pow_op(map1[i], value);
+ break;
+ }
+}
+
+template <class T1, class T2, class T3>
+static void DoBinaryConstOp(T1 *map1, T2 value, T3 *map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_BIN_ADD:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)add_op((T2)map1[i], value);
+ break;
+ case IM_BIN_SUB:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)sub_op((T2)map1[i], value);
+ break;
+ case IM_BIN_MUL:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)mul_op((T2)map1[i], value);
+ break;
+ case IM_BIN_DIV:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)div_op((T2)map1[i], value);
+ break;
+ case IM_BIN_DIFF:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)diff_op((T2)map1[i], value);
+ break;
+ case IM_BIN_MIN:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)min_op((T2)map1[i], value);
+ break;
+ case IM_BIN_MAX:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)max_op((T2)map1[i], value);
+ break;
+ case IM_BIN_POW:
+ for (i = 0; i < count; i++)
+ map[i] = (T3)pow_op((T2)map1[i], value);
+ break;
+ }
+}
+
+template <class T1>
+static void DoBinaryConstOpByte(T1 *map1, int value, imbyte *map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_BIN_ADD:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(add_op((int)map1[i], value));
+ break;
+ case IM_BIN_SUB:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(sub_op((int)map1[i], value));
+ break;
+ case IM_BIN_MUL:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(mul_op((int)map1[i], value));
+ break;
+ case IM_BIN_DIV:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(div_op((int)map1[i], value));
+ break;
+ case IM_BIN_DIFF:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(diff_op((int)map1[i], value));
+ break;
+ case IM_BIN_MIN:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(min_op((int)map1[i], value));
+ break;
+ case IM_BIN_MAX:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(max_op((int)map1[i], value));
+ break;
+ case IM_BIN_POW:
+ for (i = 0; i < count; i++)
+ map[i] = (imbyte)crop_byte(pow_op((int)map1[i], value));
+ break;
+ }
+}
+
+void imProcessArithmeticConstOp(const imImage* src_image1, float value, imImage* dst_image, int op)
+{
+ int count = src_image1->count;
+
+ for (int i = 0; i < src_image1->depth; i++)
+ {
+ switch(src_image1->data_type)
+ {
+ case IM_BYTE:
+ if (dst_image->data_type == IM_FLOAT)
+ DoBinaryConstOp((imbyte*)src_image1->data[i], (float)value, (float*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_USHORT)
+ DoBinaryConstOp((imbyte*)src_image1->data[i], (imushort)value, (imushort*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_INT)
+ DoBinaryConstOp((imbyte*)src_image1->data[i], (int)value, (int*)dst_image->data[i], count, op);
+ else
+ DoBinaryConstOpByte((imbyte*)src_image1->data[i], (int)value, (imbyte*)dst_image->data[i], count, op);
+ break;
+ case IM_USHORT:
+ if (dst_image->data_type == IM_FLOAT)
+ DoBinaryConstOp((imushort*)src_image1->data[i], (float)value, (float*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_INT)
+ DoBinaryConstOp((imushort*)src_image1->data[i], (int)value, (int*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_BYTE)
+ DoBinaryConstOpByte((imushort*)src_image1->data[i], (int)value, (imbyte*)dst_image->data[i], count, op);
+ else
+ DoBinaryConstOp((imushort*)src_image1->data[i], (imushort)value, (imushort*)dst_image->data[i], count, op);
+ break;
+ case IM_INT:
+ if (dst_image->data_type == IM_FLOAT)
+ DoBinaryConstOp((int*)src_image1->data[i], (float)value, (float*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_USHORT)
+ DoBinaryConstOp((int*)src_image1->data[i], (int)value, (imushort*)dst_image->data[i], count, op);
+ else if (dst_image->data_type == IM_BYTE)
+ DoBinaryConstOpByte((int*)src_image1->data[i], (int)value, (imbyte*)dst_image->data[i], count, op);
+ else
+ DoBinaryConstOp((int*)src_image1->data[i], (int)value, (int*)dst_image->data[i], count, op);
+ break;
+ case IM_FLOAT:
+ DoBinaryConstOp((float*)src_image1->data[i], (float)value, (float*)dst_image->data[i], count, op);
+ break;
+ case IM_CFLOAT:
+ DoBinaryConstOpCpxReal((imcfloat*)src_image1->data[i], (float)value, (imcfloat*)dst_image->data[i], count, op);
+ break;
+ }
+ }
+}
+
+void imProcessMultipleMean(const imImage** src_image_list, int src_image_count, imImage* dst_image)
+{
+ const imImage* image1 = src_image_list[0];
+
+ int data_type = image1->data_type;
+ if (image1->data_type == IM_BYTE)
+ data_type = IM_USHORT;
+
+ imImage *acum_image = imImageCreate(image1->width, image1->height, image1->color_space, data_type);
+ if (!acum_image)
+ return;
+
+ for(int i = 0; i < src_image_count; i++)
+ {
+ const imImage *image = src_image_list[i];
+ imProcessArithmeticOp(image, acum_image, acum_image, IM_BIN_ADD); /* acum_image += image */
+
+ }
+
+ imProcessArithmeticConstOp(acum_image, float(src_image_count), dst_image, IM_BIN_DIV);
+
+ imImageDestroy(acum_image);
+}
+
+void imProcessMultipleStdDev(const imImage** src_image_list, int src_image_count, const imImage *mean_image, imImage* dst_image)
+{
+ imImage* aux_image = imImageClone(dst_image);
+ if (!aux_image)
+ return;
+
+ // sdtdev = sqrt( sum(sqr(x - m)) / N)
+
+ // a = sum(sqr(x - m))
+ for(int i = 0; i < src_image_count; i++)
+ {
+ // aux_image = image - mean_image
+ imProcessArithmeticOp(src_image_list[i], mean_image, aux_image, IM_BIN_SUB);
+
+ // aux_image = aux_image * aux_image
+ imProcessUnArithmeticOp(aux_image, aux_image, IM_UN_SQR);
+
+ // dst_image += aux_image
+ imProcessArithmeticOp(aux_image, dst_image, dst_image, IM_BIN_ADD);
+ }
+
+ // dst_image = dst_image / src_image_count;
+ imProcessArithmeticConstOp(dst_image, float(src_image_count), dst_image, IM_BIN_DIV);
+
+ // dst_image = sqrt(dst_image);
+ imProcessUnArithmeticOp(dst_image, dst_image, IM_UN_SQRT);
+
+ imImageDestroy(aux_image);
+}
+
+template <class DT>
+static float AutoCovCalc(int width, int height, DT *src_map, DT *mean_map, int x, int y, float count)
+{
+ float value = 0;
+ int ni = height - y;
+ int nj = width - x;
+ int offset, offset1;
+ int next = width*y + x;
+
+ for (int i = 0; i < ni; i++)
+ {
+ for (int j = 0; j < nj; j++)
+ {
+ offset = width*i + j;
+ offset1 = offset + next;
+ value += float(src_map[offset] - mean_map[offset]) * float(src_map[offset1] - mean_map[offset1]);
+ }
+ }
+
+ return (value/count);
+}
+
+template <class DT>
+static int AutoCov(int width, int height, DT *src_map, DT *mean_map, float *dst_map, int counter)
+{
+ int count = width*height;
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ *dst_map = AutoCovCalc(width, height, src_map, mean_map, x, y, (float)count);
+ dst_map++;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+int imProcessAutoCovariance(const imImage* image, const imImage* mean_image, imImage* dst_image)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin("Auto Convariance");
+ imCounterTotal(counter, image->depth*image->height, "Processing...");
+
+ for (int i = 0; i < image->depth; i++)
+ {
+ switch(image->data_type)
+ {
+ case IM_BYTE:
+ ret = AutoCov(image->width, image->height, (imbyte*)image->data[i], (imbyte*)mean_image->data[i], (float*)dst_image->data[i], counter);
+ break;
+ case IM_USHORT:
+ ret = AutoCov(image->width, image->height, (imushort*)image->data[i], (imushort*)mean_image->data[i], (float*)dst_image->data[i], counter);
+ break;
+ case IM_INT:
+ ret = AutoCov(image->width, image->height, (int*)image->data[i], (int*)mean_image->data[i], (float*)dst_image->data[i], counter);
+ break;
+ case IM_FLOAT:
+ ret = AutoCov(image->width, image->height, (float*)image->data[i], (float*)mean_image->data[i], (float*)dst_image->data[i], counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+void imProcessMultiplyConj(const imImage* image1, const imImage* image2, imImage* NewImage)
+{
+ int total_count = image1->count*image1->depth;
+
+ imcfloat* map = (imcfloat*)NewImage->data[0];
+ imcfloat* map1 = (imcfloat*)image1->data[0];
+ imcfloat* map2 = (imcfloat*)image2->data[0];
+ imcfloat tmp; // this will allow an in-place operation
+
+ for (int i = 0; i < total_count; i++)
+ {
+ tmp.real = map1->real * map2->real + map1->imag * map2->imag;
+ tmp.imag = map1->real * map2->imag - map1->imag * map2->real;
+ *map = tmp;
+
+ map++;
+ map1++;
+ map2++;
+ }
+}
diff --git a/im/src/process/im_arithmetic_un.cpp b/im/src/process/im_arithmetic_un.cpp
new file mode 100755
index 0000000..e4dba8a
--- /dev/null
+++ b/im/src/process/im_arithmetic_un.cpp
@@ -0,0 +1,256 @@
+/** \file
+ * \brief Unary Arithmetic Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_arithmetic_un.cpp,v 1.2 2009/10/01 02:56:58 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math.h>
+#include <im_complex.h>
+
+#include "im_process_pon.h"
+#include "im_math_op.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+// Fake complex operations for real types
+static inline imbyte conj_op(const imbyte& v) {return v;}
+static inline imushort conj_op(const imushort& v) {return v;}
+static inline int conj_op(const int& v) {return v;}
+static inline float conj_op(const float& v) {return v;}
+static inline imbyte cpxnorm_op(const imbyte& v) {return v;}
+static inline imushort cpxnorm_op(const imushort& v) {return v;}
+static inline int cpxnorm_op(const int& v) {return v;}
+static inline float cpxnorm_op(const float& v) {return v;}
+
+static inline imcfloat conj_op(const imcfloat& v)
+{
+ imcfloat r;
+ r.real = v.real;
+ r.imag = -v.imag;
+ return r;
+}
+
+static inline imcfloat cpxnorm_op(const imcfloat& v)
+{
+ imcfloat r;
+ float rmag = cpxmag(v);
+ if (rmag != 0.0f)
+ {
+ r.real = v.real/rmag;
+ r.imag = v.imag/rmag;
+ }
+ else
+ {
+ r.real = 0.0f;
+ r.imag = 0.0f;
+ }
+ return r;
+}
+
+template <class T1, class T2>
+static void DoUnaryOp(T1 *map, T2 *new_map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_UN_ABS:
+ for (i = 0; i < count; i++)
+ new_map[i] = abs_op((T2)map[i]);
+ break;
+ case IM_UN_INV:
+ for (i = 0; i < count; i++)
+ new_map[i] = inv_op((T2)map[i]);
+ break;
+ case IM_UN_EQL:
+ for (i = 0; i < count; i++)
+ new_map[i] = (T2)map[i];
+ break;
+ case IM_UN_LESS:
+ for (i = 0; i < count; i++)
+ new_map[i] = less_op((T2)map[i]);
+ break;
+ case IM_UN_SQR:
+ for (i = 0; i < count; i++)
+ new_map[i] = sqr_op((T2)map[i]);
+ break;
+ case IM_UN_SQRT:
+ for (i = 0; i < count; i++)
+ new_map[i] = sqrt_op((T2)map[i]);
+ break;
+ case IM_UN_LOG:
+ for (i = 0; i < count; i++)
+ new_map[i] = log_op((T2)map[i]);
+ break;
+ case IM_UN_SIN:
+ for (i = 0; i < count; i++)
+ new_map[i] = sin_op((T2)map[i]);
+ break;
+ case IM_UN_COS:
+ for (i = 0; i < count; i++)
+ new_map[i] = cos_op((T2)map[i]);
+ break;
+ case IM_UN_EXP:
+ for (i = 0; i < count; i++)
+ new_map[i] = exp_op((T2)map[i]);
+ break;
+ case IM_UN_CONJ:
+ for (i = 0; i < count; i++)
+ new_map[i] = conj_op((T2)map[i]);
+ break;
+ case IM_UN_CPXNORM:
+ for (i = 0; i < count; i++)
+ new_map[i] = cpxnorm_op((T2)map[i]);
+ break;
+ }
+}
+
+template <class T1>
+static void DoUnaryOpByte(T1 *map, imbyte *new_map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_UN_ABS:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(abs_op((int)map[i]));
+ break;
+ case IM_UN_INV:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(inv_op((int)map[i])); /* will always be 0 */
+ break;
+ case IM_UN_EQL:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte((int)map[i]);
+ break;
+ case IM_UN_LESS:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(less_op((int)map[i]));
+ break;
+ case IM_UN_SQR:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(sqr_op((int)map[i]));
+ break;
+ case IM_UN_SQRT:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(sqrt_op((int)map[i]));
+ break;
+ case IM_UN_LOG:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(log_op((int)map[i]));
+ break;
+ case IM_UN_SIN:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(sin_op((int)map[i]));
+ break;
+ case IM_UN_COS:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(cos_op((int)map[i]));
+ break;
+ case IM_UN_EXP:
+ for (i = 0; i < count; i++)
+ new_map[i] = (imbyte)crop_byte(exp_op((int)map[i]));
+ break;
+ }
+}
+
+void imProcessUnArithmeticOp(const imImage* src_image, imImage* dst_image, int op)
+{
+ int total_count = src_image->count * src_image->depth;
+
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ if (dst_image->data_type == IM_FLOAT)
+ DoUnaryOp((imbyte*)src_image->data[0], (float*)dst_image->data[0], total_count, op);
+ else if (dst_image->data_type == IM_INT)
+ DoUnaryOp((imbyte*)src_image->data[0], (int*)dst_image->data[0], total_count, op);
+ else if (dst_image->data_type == IM_USHORT)
+ DoUnaryOp((imbyte*)src_image->data[0], (imushort*)dst_image->data[0], total_count, op);
+ else
+ DoUnaryOpByte((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], total_count, op);
+ break;
+ case IM_USHORT:
+ if (dst_image->data_type == IM_BYTE)
+ DoUnaryOpByte((imushort*)src_image->data[0], (imbyte*)dst_image->data[0], total_count, op);
+ else if (dst_image->data_type == IM_INT)
+ DoUnaryOp((imushort*)src_image->data[0], (int*)dst_image->data[0], total_count, op);
+ else if (dst_image->data_type == IM_FLOAT)
+ DoUnaryOp((imushort*)src_image->data[0], (float*)dst_image->data[0], total_count, op);
+ else
+ DoUnaryOp((imushort*)src_image->data[0], (imushort*)dst_image->data[0], total_count, op);
+ break;
+ case IM_INT:
+ if (dst_image->data_type == IM_BYTE)
+ DoUnaryOpByte((int*)src_image->data[0], (imbyte*)dst_image->data[0], total_count, op);
+ else if (dst_image->data_type == IM_USHORT)
+ DoUnaryOp((int*)src_image->data[0], (imushort*)dst_image->data[0], total_count, op);
+ else if (dst_image->data_type == IM_FLOAT)
+ DoUnaryOp((int*)src_image->data[0], (float*)dst_image->data[0], total_count, op);
+ else
+ DoUnaryOp((int*)src_image->data[0], (int*)dst_image->data[0], total_count, op);
+ break;
+ case IM_FLOAT:
+ DoUnaryOp((float*)src_image->data[0], (float*)dst_image->data[0], total_count, op);
+ break;
+ case IM_CFLOAT:
+ DoUnaryOp((imcfloat*)src_image->data[0], (imcfloat*)dst_image->data[0], total_count, op);
+ break;
+ }
+}
+
+void imProcessSplitComplex(const imImage* image, imImage* NewImage1, imImage* NewImage2, int polar)
+{
+ int total_count = image->count*image->depth;
+
+ imcfloat* map = (imcfloat*)image->data[0];
+ float* map1 = (float*)NewImage1->data[0];
+ float* map2 = (float*)NewImage2->data[0];
+
+ for (int i = 0; i < total_count; i++)
+ {
+ if (polar)
+ {
+ map1[i] = cpxmag(map[i]);
+ map2[i] = cpxphase(map[i]);
+ }
+ else
+ {
+ map1[i] = map[i].real;
+ map2[i] = map[i].imag;
+ }
+ }
+}
+
+void imProcessMergeComplex(const imImage* image1, const imImage* image2, imImage* NewImage, int polar)
+{
+ int total_count = image1->count*image1->depth;
+
+ imcfloat* map = (imcfloat*)NewImage->data[0];
+ float* map1 = (float*)image1->data[0];
+ float* map2 = (float*)image2->data[0];
+
+ for (int i = 0; i < total_count; i++)
+ {
+ if (polar)
+ {
+ float phase = map2[i];
+ if (phase > 180) phase -= 360;
+ phase /= 57.2957795f;
+
+ map[i].real = (float)(map1[i] * cos(phase));
+ map[i].imag = (float)(map1[i] * sin(phase));
+ }
+ else
+ {
+ map[i].real = map1[i];
+ map[i].imag = map2[i];
+ }
+ }
+}
diff --git a/im/src/process/im_canny.cpp b/im/src/process/im_canny.cpp
new file mode 100755
index 0000000..d749fc0
--- /dev/null
+++ b/im/src/process/im_canny.cpp
@@ -0,0 +1,254 @@
+/** \file
+ * \brief Canny Edge Detector
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_canny.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+#include <im.h>
+
+#include "im_process_loc.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <memory.h>
+
+/* Scale floating point magnitudes to 8 bits */
+static float MAG_SCALE;
+
+/* Biggest possible filter mask */
+#define MAX_MASK_SIZE 100
+
+static float ** f2d (int nr, int nc);
+static float gauss(float x, float sigma);
+static float dGauss (float x, float sigma);
+static float meanGauss (float x, float sigma);
+static void seperable_convolution (const imImage* im, float *gau, int width, float **smx, float **smy);
+static void dxy_seperable_convolution (float** im, int nr, int nc, float *gau, int width, float **sm, int which);
+static void nonmax_suppress (float **dx, float **dy, imImage* mag);
+
+void imProcessCanny(const imImage* im, imImage* NewImage, float stddev)
+{
+ int width = 1;
+ float **smx,**smy;
+ float **dx,**dy;
+ int i;
+ float gau[MAX_MASK_SIZE], dgau[MAX_MASK_SIZE];
+
+/* Create a Gaussian and a derivative of Gaussian filter mask */
+ for(i=0; i<MAX_MASK_SIZE; i++)
+ {
+ gau[i] = meanGauss ((float)i, stddev);
+ if (gau[i] < 0.005)
+ {
+ width = i;
+ break;
+ }
+ dgau[i] = dGauss ((float)i, stddev);
+ }
+
+ smx = f2d (im->height, im->width);
+ smy = f2d (im->height, im->width);
+
+/* Convolution of source image with a Gaussian in X and Y directions */
+ seperable_convolution (im, gau, width, smx, smy);
+
+ MAG_SCALE = 0;
+
+/* Now convolve smoothed data with a derivative */
+ dx = f2d (im->height, im->width);
+ dxy_seperable_convolution (smx, im->height, im->width, dgau, width, dx, 1);
+ free(smx[0]); free(smx);
+
+ dy = f2d (im->height, im->width);
+ dxy_seperable_convolution (smy, im->height, im->width, dgau, width, dy, 0);
+ free(smy[0]); free(smy);
+
+ if (MAG_SCALE)
+ MAG_SCALE = 255.0f/(1.4142f*MAG_SCALE);
+
+ /* Non-maximum suppression - edge pixels should be a local max */
+ nonmax_suppress (dx, dy, NewImage);
+
+ free(dx[0]); free(dx);
+ free(dy[0]); free(dy);
+}
+
+static float norm (float x, float y)
+{
+ return (float) sqrt ( (double)(x*x + y*y) );
+}
+
+static float ** f2d (int nr, int nc)
+{
+ float **x, *y;
+ int i;
+
+ x = (float **)calloc ( nr, sizeof (float *) );
+ if (!x)
+ return NULL;
+
+ y = (float *)calloc ( nr*nc, sizeof (float) );
+ if (!y)
+ return NULL;
+
+ for (i=0; i<nr; i++)
+ {
+ x[i] = y + i*nc;
+ }
+
+ return x;
+}
+
+/* Gaussian */
+static float gauss(float x, float sigma)
+{
+ return (float)exp((double) ((-x*x)/(2*sigma*sigma)));
+}
+
+static float meanGauss (float x, float sigma)
+{
+ float z;
+ z = (gauss(x,sigma)+gauss(x+0.5f,sigma)+gauss(x-0.5f,sigma))/3.0f;
+// z = z/(3.1415f*2.0f*sigma*sigma);
+ return z;
+}
+
+/* First derivative of Gaussian */
+static float dGauss (float x, float sigma)
+{
+// return -x/(sigma*sigma) * gauss(x, sigma);
+ return -x * gauss(x, sigma);
+}
+
+static void seperable_convolution (const imImage* im, float *gau, int width, float **smx, float **smy)
+{
+ int i,j,k, I1, I2, nr, nc;
+ float x, y;
+ unsigned char* im_data = (unsigned char*)im->data[0];
+
+ nr = im->height;
+ nc = im->width;
+
+ for (i=0; i<nr; i++)
+ {
+ for (j=0; j<nc; j++)
+ {
+ x = gau[0] * im_data[i*im->width + j]; y = gau[0] * im_data[i*im->width + j];
+ for (k=1; k<width; k++)
+ {
+ I1 = (i+k)%nr; I2 = (i-k+nr)%nr;
+ y += gau[k]*im_data[I1*im->width + j] + gau[k]*im_data[I2*im->width + j];
+ I1 = (j+k)%nc; I2 = (j-k+nc)%nc;
+ x += gau[k]*im_data[i*im->width + I1] + gau[k]*im_data[i*im->width + I2];
+ }
+ smx[i][j] = x; smy[i][j] = y;
+ }
+ }
+}
+
+static void dxy_seperable_convolution (float** im, int nr, int nc, float *gau, int width, float **sm, int which)
+{
+ int i,j,k, I1, I2;
+ float x;
+
+ for (i=0; i<nr; i++)
+ {
+ for (j=0; j<nc; j++)
+ {
+ x = 0.0;
+ for (k=1; k<width; k++)
+ {
+ if (which == 0)
+ {
+ I1 = (i+k)%nr; I2 = (i-k+nr)%nr;
+ x += -gau[k]*im[I1][j] + gau[k]*im[I2][j];
+ }
+ else
+ {
+ I1 = (j+k)%nc; I2 = (j-k+nc)%nc;
+ x += -gau[k]*im[i][I1] + gau[k]*im[i][I2];
+ }
+ }
+ sm[i][j] = x;
+
+ if (x > MAG_SCALE)
+ MAG_SCALE = x;
+ }
+ }
+}
+
+static unsigned char tobyte(float x)
+{
+ if (x > 255) return 255;
+ return (unsigned char)x;
+}
+
+static void nonmax_suppress (float **dx, float **dy, imImage* mag)
+{
+ int i,j;
+ float xx, yy, g2, g1, g3, g4, g, xc, yc;
+ unsigned char* mag_data = (unsigned char*)mag->data[0];
+
+ for (i=1; i<mag->height-1; i++)
+ {
+ for (j=1; j<mag->width-1; j++)
+ {
+ /* Treat the x and y derivatives as components of a vector */
+ xc = dx[i][j];
+ yc = dy[i][j];
+ if (fabs(xc)<0.01 && fabs(yc)<0.01) continue;
+
+ g = norm (xc, yc);
+
+ /* Follow the gradient direction, as indicated by the direction of
+ the vector (xc, yc); retain pixels that are a local maximum. */
+
+ if (fabs(yc) > fabs(xc))
+ {
+ /* The Y component is biggest, so gradient direction is basically UP/DOWN */
+ xx = (float)(fabs(xc)/fabs(yc));
+ yy = 1.0;
+
+ g2 = norm (dx[i-1][j], dy[i-1][j]);
+ g4 = norm (dx[i+1][j], dy[i+1][j]);
+ if (xc*yc > 0.0)
+ {
+ g3 = norm (dx[i+1][j+1], dy[i+1][j+1]);
+ g1 = norm (dx[i-1][j-1], dy[i-1][j-1]);
+ }
+ else
+ {
+ g3 = norm (dx[i+1][j-1], dy[i+1][j-1]);
+ g1 = norm (dx[i-1][j+1], dy[i-1][j+1]);
+ }
+
+ }
+ else
+ {
+ /* The X component is biggest, so gradient direction is basically LEFT/RIGHT */
+ xx = (float)(fabs(yc)/fabs(xc));
+ yy = 1.0;
+
+ g2 = norm (dx[i][j+1], dy[i][j+1]);
+ g4 = norm (dx[i][j-1], dy[i][j-1]);
+ if (xc*yc > 0.0)
+ {
+ g3 = norm (dx[i-1][j-1], dy[i-1][j-1]);
+ g1 = norm (dx[i+1][j+1], dy[i+1][j+1]);
+ }
+ else
+ {
+ g1 = norm (dx[i-1][j+1], dy[i-1][j+1]);
+ g3 = norm (dx[i+1][j-1], dy[i+1][j-1]);
+ }
+ }
+
+ /* Compute the interpolated value of the gradient magnitude */
+ if ( (g > (xx*g1 + (yy-xx)*g2)) && (g > (xx*g3 + (yy-xx)*g4)) )
+ {
+ mag_data[i*mag->width + j] = tobyte(g*MAG_SCALE);
+ }
+ }
+ }
+}
diff --git a/im/src/process/im_color.cpp b/im/src/process/im_color.cpp
new file mode 100755
index 0000000..b27d4b3
--- /dev/null
+++ b/im/src/process/im_color.cpp
@@ -0,0 +1,255 @@
+/** \file
+ * \brief Color Processing Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_color.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+#include <im.h>
+#include <im_util.h>
+#include <im_colorhsi.h>
+#include <im_palette.h>
+
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+
+static void rgb2yrgb(imbyte* r, imbyte* g, imbyte* b, imbyte* y)
+{
+ int ri,gi,bi;
+
+ *y = (imbyte)((299*(*r) + 587*(*g) + 114*(*b)) / 1000);
+ ri = (*r) - (*y) + 128;
+ gi = (*g) - (*y) + 128;
+ bi = (*b) - (*y) + 128;
+
+ if (ri < 0) ri = 0;
+ if (gi < 0) gi = 0;
+ if (bi < 0) bi = 0;
+
+ *r = (imbyte)ri;
+ *g = (imbyte)gi;
+ *b = (imbyte)bi;
+}
+
+void imProcessSplitYChroma(const imImage* src_image, imImage* y_image, imImage* chroma_image)
+{
+ imbyte Y,
+ *red=(imbyte*)src_image->data[0],
+ *green=(imbyte*)src_image->data[1],
+ *blue=(imbyte*)src_image->data[2],
+ *red2=(imbyte*)chroma_image->data[0],
+ *green2=(imbyte*)chroma_image->data[1],
+ *blue2=(imbyte*)chroma_image->data[2],
+ *map1=(imbyte*)y_image->data[0];
+
+ for (int i = 0; i < src_image->count; i++)
+ {
+ imbyte R = red[i];
+ imbyte G = green[i];
+ imbyte B = blue[i];
+
+ rgb2yrgb(&R, &G, &B, &Y);
+
+ map1[i] = Y;
+
+ red2[i] = R;
+ green2[i] = G;
+ blue2[i] = B;
+ }
+}
+
+static void DoSplitHSIFloat(float** data, float* hue, float* saturation, float* intensity, int count)
+{
+ float *red=data[0],
+ *green=data[1],
+ *blue=data[2];
+
+ for (int i = 0; i < count; i++)
+ {
+ imColorRGB2HSI(red[i], green[i], blue[i], &hue[i], &saturation[i], &intensity[i]);
+ }
+}
+
+static void DoSplitHSIByte(imbyte** data, float* hue, float* saturation, float* intensity, int count)
+{
+ imbyte *red=data[0],
+ *green=data[1],
+ *blue=data[2];
+
+ for (int i = 0; i < count; i++)
+ {
+ imColorRGB2HSIbyte(red[i], green[i], blue[i], &hue[i], &saturation[i], &intensity[i]);
+ }
+}
+
+void imProcessSplitHSI(const imImage* image, imImage* image1, imImage* image2, imImage* image3)
+{
+ switch(image->data_type)
+ {
+ case IM_BYTE:
+ DoSplitHSIByte((imbyte**)image->data, (float*)image1->data[0], (float*)image2->data[0], (float*)image3->data[0], image->count);
+ break;
+ case IM_FLOAT:
+ DoSplitHSIFloat((float**)image->data, (float*)image1->data[0], (float*)image2->data[0], (float*)image3->data[0], image->count);
+ break;
+ }
+
+ imImageSetPalette(image1, imPaletteHues(), 256);
+}
+
+static void DoMergeHSIFloat(float** data, float* hue, float* saturation, float* intensity, int count)
+{
+ float *red=data[0],
+ *green=data[1],
+ *blue=data[2];
+
+ for (int i = 0; i < count; i++)
+ {
+ imColorHSI2RGB(hue[i], saturation[i], intensity[i], &red[i], &green[i], &blue[i]);
+ }
+}
+
+static void DoMergeHSIByte(imbyte** data, float* hue, float* saturation, float* intensity, int count)
+{
+ imbyte *red=data[0],
+ *green=data[1],
+ *blue=data[2];
+
+ for (int i = 0; i < count; i++)
+ {
+ imColorHSI2RGBbyte(hue[i], saturation[i], intensity[i], &red[i], &green[i], &blue[i]);
+ }
+}
+
+void imProcessMergeHSI(const imImage* image1, const imImage* image2, const imImage* image3, imImage* image)
+{
+ switch(image->data_type)
+ {
+ case IM_BYTE:
+ DoMergeHSIByte((imbyte**)image->data, (float*)image1->data[0], (float*)image2->data[0], (float*)image3->data[0], image->count);
+ break;
+ case IM_FLOAT:
+ DoMergeHSIFloat((float**)image->data, (float*)image1->data[0], (float*)image2->data[0], (float*)image3->data[0], image->count);
+ break;
+ }
+}
+
+void imProcessSplitComponents(const imImage* src_image, imImage** dst_image)
+{
+ memcpy(dst_image[0]->data[0], src_image->data[0], src_image->plane_size);
+ memcpy(dst_image[1]->data[0], src_image->data[1], src_image->plane_size);
+ memcpy(dst_image[2]->data[0], src_image->data[2], src_image->plane_size);
+ if (imColorModeDepth(src_image->color_space) == 4)
+ memcpy(dst_image[3]->data[0], src_image->data[3], src_image->plane_size);
+}
+
+void imProcessMergeComponents(const imImage** src_image, imImage* dst_image)
+{
+ memcpy(dst_image->data[0], src_image[0]->data[0], dst_image->plane_size);
+ memcpy(dst_image->data[1], src_image[1]->data[0], dst_image->plane_size);
+ memcpy(dst_image->data[2], src_image[2]->data[0], dst_image->plane_size);
+ if (imColorModeDepth(dst_image->color_space) == 4)
+ memcpy(dst_image->data[3], src_image[3]->data[0], dst_image->plane_size);
+}
+
+template <class T>
+static void DoNormalizeComp(T** src_data, float** dst_data, int count, int depth)
+{
+ int d;
+ T* src_pdata[4];
+ float* dst_pdata[4];
+
+ for(d = 0; d < depth; d++)
+ {
+ dst_pdata[d] = dst_data[d];
+ src_pdata[d] = src_data[d];
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ float sum = 0;
+ for(d = 0; d < depth; d++)
+ sum += (float)*(src_pdata[d]);
+
+ for(d = 0; d < depth; d++)
+ {
+ if (sum == 0)
+ *(dst_pdata[d]) = 0;
+ else
+ *(dst_pdata[d]) = (float)*(src_pdata[d]) / sum;
+
+ dst_pdata[d]++;
+ src_pdata[d]++;
+ }
+ }
+}
+
+void imProcessNormalizeComponents(const imImage* src_image, imImage* dst_image)
+{
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ DoNormalizeComp((imbyte**)src_image->data, (float**)dst_image->data, src_image->count, src_image->depth);
+ break;
+ case IM_USHORT:
+ DoNormalizeComp((imushort**)src_image->data, (float**)dst_image->data, src_image->count, src_image->depth);
+ break;
+ case IM_INT:
+ DoNormalizeComp((int**)src_image->data, (float**)dst_image->data, src_image->count, src_image->depth);
+ break;
+ case IM_FLOAT:
+ DoNormalizeComp((float**)src_image->data, (float**)dst_image->data, src_image->count, src_image->depth);
+ break;
+ }
+}
+
+template <class T>
+static void DoReplaceColor(T *src_data, T *dst_data, int width, int height, int depth, float* src_color, float* dst_color)
+{
+ int d, count = width*height;
+ for (int i = 0; i < count; i++)
+ {
+ int equal = 1;
+ for (d = 0; d < depth; d++)
+ {
+ if (*(src_data+d*count) != (T)src_color[d])
+ {
+ equal = 0;
+ break;
+ }
+ }
+
+ for (d = 0; d < depth; d++)
+ {
+ if (equal)
+ *(dst_data+d*count) = (T)dst_color[d];
+ else
+ *(dst_data+d*count) = *(src_data+d*count);
+ }
+
+ src_data++;
+ dst_data++;
+ }
+}
+
+void imProcessReplaceColor(const imImage* src_image, imImage* dst_image, float* src_color, float* dst_color)
+{
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ DoReplaceColor((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], src_image->width, src_image->height, src_image->depth, src_color, dst_color);
+ break;
+ case IM_USHORT:
+ DoReplaceColor((imushort*)src_image->data[0], (imushort*)dst_image->data[0], src_image->width, src_image->height, src_image->depth, src_color, dst_color);
+ break;
+ case IM_INT:
+ DoReplaceColor((int*)src_image->data[0], (int*)dst_image->data[0], src_image->width, src_image->height, src_image->depth, src_color, dst_color);
+ break;
+ case IM_FLOAT:
+ DoReplaceColor((float*)src_image->data[0], (float*)dst_image->data[0], src_image->width, src_image->height, src_image->depth, src_color, dst_color);
+ break;
+ }
+}
diff --git a/im/src/process/im_convolve.cpp b/im/src/process/im_convolve.cpp
new file mode 100755
index 0000000..a88a25c
--- /dev/null
+++ b/im/src/process/im_convolve.cpp
@@ -0,0 +1,1594 @@
+/** \file
+ * \brief Convolution Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_convolve.cpp,v 1.2 2009/10/01 02:56:58 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_counter.h>
+#include <im_complex.h>
+#include <im_math_op.h>
+#include <im_image.h>
+#include <im_kernel.h>
+
+#include "im_process_loc.h"
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+#include <math.h>
+
+/* Rotating Kernels
+3x3
+ 6 7 8 7 8 5
+ 3 4 5 6 4 2
+ 0 1 2 3 0 1
+
+5x5
+ 20 21 22 23 24 22 23 24 19 14
+ 15 16 17 18 19 21 17 18 13 9
+ 10 11 12 13 14 20 16 12 8 4
+ 5 6 7 8 9 15 11 6 7 3
+ 0 1 2 3 4 10 5 0 1 2
+
+7x7
+ 42 43 44 45 46 47 48 45 46 47 48 41 34 27
+ 35 36 37 38 39 40 41 44 38 39 40 33 26 20
+ 28 29 30 31 32 33 34 43 37 31 32 25 19 13
+ 21 22 23 24 25 26 27 42 36 30 24 18 12 6
+ 14 15 16 17 18 19 20 35 29 23 16 17 11 5
+ 7 8 9 10 11 12 13 28 22 15 8 9 10 4
+ 0 1 2 3 4 5 6 21 14 7 0 1 2 3
+
+ TO DO: a generic odd rotation function...
+*/
+
+template <class KT>
+static void iRotateKernel(KT* kernel_map, int kernel_size)
+{
+ KT temp;
+
+ switch (kernel_size)
+ {
+ case 3:
+ {
+ temp = kernel_map[0];
+ kernel_map[0] = kernel_map[3];
+ kernel_map[3] = kernel_map[6];
+ kernel_map[6] = kernel_map[7];
+ kernel_map[7] = kernel_map[8];
+ kernel_map[8] = kernel_map[5];
+ kernel_map[5] = kernel_map[2];
+ kernel_map[2] = kernel_map[1];
+ kernel_map[1] = temp;
+ }
+ break;
+ case 5:
+ {
+ temp = kernel_map[0];
+ kernel_map[0] = kernel_map[10];
+ kernel_map[10] = kernel_map[20];
+ kernel_map[20] = kernel_map[22];
+ kernel_map[22] = kernel_map[24];
+ kernel_map[24] = kernel_map[14];
+ kernel_map[14] = kernel_map[4];
+ kernel_map[4] = kernel_map[2];
+ kernel_map[2] = temp;
+
+ temp = kernel_map[5];
+ kernel_map[5] = kernel_map[15];
+ kernel_map[15] = kernel_map[21];
+ kernel_map[21] = kernel_map[23];
+ kernel_map[23] = kernel_map[19];
+ kernel_map[19] = kernel_map[9];
+ kernel_map[9] = kernel_map[3];
+ kernel_map[3] = kernel_map[1];
+ kernel_map[1] = temp;
+
+ temp = kernel_map[6];
+ kernel_map[6] = kernel_map[11];
+ kernel_map[11] = kernel_map[16];
+ kernel_map[16] = kernel_map[17];
+ kernel_map[17] = kernel_map[18];
+ kernel_map[18] = kernel_map[13];
+ kernel_map[13] = kernel_map[8];
+ kernel_map[8] = kernel_map[7];
+ kernel_map[7] = temp;
+ }
+ break;
+ case 7:
+ {
+ temp = kernel_map[2];
+ kernel_map[2] = kernel_map[7];
+ kernel_map[7] = kernel_map[28];
+ kernel_map[28] = kernel_map[43];
+ kernel_map[43] = kernel_map[46];
+ kernel_map[46] = kernel_map[41];
+ kernel_map[41] = kernel_map[20];
+ kernel_map[20] = kernel_map[5];
+ kernel_map[5] = temp;
+
+ temp = kernel_map[1];
+ kernel_map[1] = kernel_map[14];
+ kernel_map[14] = kernel_map[35];
+ kernel_map[35] = kernel_map[44];
+ kernel_map[44] = kernel_map[47];
+ kernel_map[47] = kernel_map[34];
+ kernel_map[34] = kernel_map[13];
+ kernel_map[13] = kernel_map[4];
+ kernel_map[4] = temp;
+
+ temp = kernel_map[0];
+ kernel_map[0] = kernel_map[21];
+ kernel_map[21] = kernel_map[42];
+ kernel_map[42] = kernel_map[45];
+ kernel_map[45] = kernel_map[48];
+ kernel_map[48] = kernel_map[27];
+ kernel_map[27] = kernel_map[6];
+ kernel_map[6] = kernel_map[3];
+ kernel_map[3] = temp;
+
+ temp = kernel_map[9];
+ kernel_map[9] = kernel_map[15];
+ kernel_map[15] = kernel_map[29];
+ kernel_map[29] = kernel_map[37];
+ kernel_map[37] = kernel_map[39];
+ kernel_map[39] = kernel_map[33];
+ kernel_map[33] = kernel_map[19];
+ kernel_map[19] = kernel_map[11];
+ kernel_map[11] = temp;
+
+ temp = kernel_map[8];
+ kernel_map[8] = kernel_map[22];
+ kernel_map[22] = kernel_map[36];
+ kernel_map[36] = kernel_map[38];
+ kernel_map[38] = kernel_map[40];
+ kernel_map[40] = kernel_map[26];
+ kernel_map[26] = kernel_map[12];
+ kernel_map[12] = kernel_map[10];
+ kernel_map[10] = temp;
+
+ temp = kernel_map[16];
+ kernel_map[16] = kernel_map[23];
+ kernel_map[23] = kernel_map[30];
+ kernel_map[30] = kernel_map[31];
+ kernel_map[31] = kernel_map[32];
+ kernel_map[32] = kernel_map[25];
+ kernel_map[25] = kernel_map[18];
+ kernel_map[18] = kernel_map[17];
+ kernel_map[17] = temp;
+ }
+ break;
+ }
+}
+
+void imProcessRotateKernel(imImage* kernel)
+{
+ if (kernel->data_type == IM_INT)
+ iRotateKernel((int*)kernel->data[0], kernel->width);
+ else
+ iRotateKernel((float*)kernel->data[0], kernel->width);
+}
+
+template <class T, class KT, class CT>
+static int DoCompassConvolve(T* map, T* new_map, int width, int height, KT* orig_kernel_map, int kernel_size, int counter, CT)
+{
+ CT value;
+ KT total, *kernel_line, kvalue;
+ int offset, new_offset, i, j, x, y, kcount;
+
+ // duplicate the kernel data so we can rotate it
+ kcount = kernel_size*kernel_size;
+ KT* kernel_map = (KT*)malloc(kcount*sizeof(KT));
+
+ int ks2 = kernel_size/2;
+
+ total = 0;
+ for(j = 0; j < kcount; j++)
+ {
+ kvalue = orig_kernel_map[j];
+ kernel_map[j] = kvalue;
+ total += kvalue;
+ }
+
+ if (total == 0)
+ total = 1;
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ CT max_value = 0;
+
+ for(int k = 0; k < 8; k++) // Rotate 8 times
+ {
+ value = 0;
+
+ for(y = -ks2; y <= ks2; y++)
+ {
+ kernel_line = kernel_map + (y+ks2)*kernel_size;
+
+ if (j + y < 0) // pass the bottom border
+ offset = -(y + j + 1) * width;
+ else if (j + y >= height) // pass the top border
+ offset = (2*height - 1 - (j + y)) * width;
+ else
+ offset = (j + y) * width;
+
+ for(x = -ks2; x <= ks2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value += kernel_line[x+ks2] * map[offset - (i + x + 1)];
+ else if (i + x >= width) // pass the right border
+ value += kernel_line[x+ks2] * map[offset + 2*width - 1 - (i + x)];
+ else if (offset != -1)
+ value += kernel_line[x+ks2] * map[offset + (i + x)];
+ }
+ }
+
+ if (abs_op(value) > max_value)
+ max_value = abs_op(value);
+
+ iRotateKernel(kernel_map, kernel_size);
+ }
+
+ max_value /= total;
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T) == size_of)
+ new_map[new_offset + i] = (T)IM_BYTECROP(max_value);
+ else
+ new_map[new_offset + i] = (T)max_value;
+ }
+
+ if (!imCounterInc(counter))
+ {
+ free(kernel_map);
+ return 0;
+ }
+ }
+
+ free(kernel_map);
+ return 1;
+}
+
+int imProcessCompassConvolve(const imImage* src_image, imImage* dst_image, imImage *kernel)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin("Compass Convolution");
+ const char* msg = (const char*)imImageGetAttribute(kernel, "Description", NULL, NULL);
+ if (!msg) msg = "Filtering...";
+ imCounterTotal(counter, src_image->depth*src_image->height, msg);
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ if (kernel->data_type == IM_INT)
+ ret = DoCompassConvolve((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, counter, (int)0);
+ else
+ ret = DoCompassConvolve((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, counter, (float)0);
+ break;
+ case IM_USHORT:
+ if (kernel->data_type == IM_INT)
+ ret = DoCompassConvolve((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, counter, (int)0);
+ else
+ ret = DoCompassConvolve((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, counter, (float)0);
+ break;
+ case IM_INT:
+ if (kernel->data_type == IM_INT)
+ ret = DoCompassConvolve((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, counter, (int)0);
+ else
+ ret = DoCompassConvolve((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, counter, (float)0);
+ break;
+ case IM_FLOAT:
+ if (kernel->data_type == IM_INT)
+ ret = DoCompassConvolve((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, counter, (float)0);
+ else
+ ret = DoCompassConvolve((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, counter, (float)0);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+template <class T, class KT, class CT>
+static int DoConvolveDual(T* map, T* new_map, int width, int height, KT* kernel_map1, KT* kernel_map2, int kernel_width, int kernel_height, int counter, CT)
+{
+ CT value1, value2, value;
+ KT total1, total2, *kernel_line;
+ int offset, new_offset, i, j, x, y;
+
+ int kh2 = kernel_height/2;
+ int kw2 = kernel_width/2;
+
+ if (kernel_height % 2 == 0) kh2--;
+ if (kernel_width % 2 == 0) kw2--;
+
+ total1 = 0;
+ for(j = 0; j < kernel_height; j++)
+ {
+ for(i = 0; i < kernel_width; i++)
+ total1 += kernel_map1[j*kernel_width + i];
+ }
+
+ if (total1 == 0)
+ total1 = 1;
+
+ total2 = 0;
+ for(j = 0; j < kernel_height; j++)
+ {
+ for(i = 0; i < kernel_width; i++)
+ total2 += kernel_map2[j*kernel_width + i];
+ }
+
+ if (total2 == 0)
+ total2 = 1;
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ value1 = 0;
+ value2 = 0;
+
+ for(y = -kh2; y <= kh2; y++)
+ {
+ if (j + y < 0) // pass the bottom border
+ offset = -(y + j + 1) * width;
+ else if (j + y >= height) // pass the top border
+ offset = (2*height - 1 - (j + y)) * width;
+ else
+ offset = (j + y) * width;
+
+ kernel_line = kernel_map1 + (y+kh2)*kernel_width;
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value1 += kernel_line[x+kw2] * map[offset - (i + x + 1)];
+ else if (i + x >= width) // pass the right border
+ value1 += kernel_line[x+kw2] * map[offset + 2*width - 1 - (i + x)];
+ else if (offset != -1)
+ value1 += kernel_line[x+kw2] * map[offset + (i + x)];
+ }
+
+ kernel_line = kernel_map2 + (y+kh2)*kernel_width;
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value2 += kernel_line[x+kw2] * map[offset - (i + x + 1)];
+ else if (i + x >= width) // pass the right border
+ value2 += kernel_line[x+kw2] * map[offset + 2*width - 1 - (i + x)];
+ else if (offset != -1)
+ value2 += kernel_line[x+kw2] * map[offset + (i + x)];
+ }
+ }
+
+ value1 /= total1;
+ value2 /= total2;
+
+ value = (CT)sqrt((double)(value1*value1 + value2*value2));
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T) == size_of)
+ new_map[new_offset + i] = (T)IM_BYTECROP(value);
+ else
+ new_map[new_offset + i] = (T)value;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+template <class KT>
+static int DoConvolveDualCpx(imcfloat* map, imcfloat* new_map, int width, int height, KT* kernel_map1, KT* kernel_map2, int kernel_width, int kernel_height, int counter)
+{
+ imcfloat value1, value2;
+ KT total1, total2, *kernel_line;
+ int offset, new_offset, i, j, x, y;
+
+ int kh2 = kernel_height/2;
+ int kw2 = kernel_width/2;
+
+ if (kernel_height % 2 == 0) kh2--;
+ if (kernel_width % 2 == 0) kw2--;
+
+ total1 = 0;
+ for(j = 0; j < kernel_height; j++)
+ {
+ for(i = 0; i < kernel_width; i++)
+ total1 += kernel_map1[j*kernel_width + i];
+ }
+
+ if (total1 == 0)
+ total1 = 1;
+
+ total2 = 0;
+ for(j = 0; j < kernel_height; j++)
+ {
+ for(i = 0; i < kernel_width; i++)
+ total2 += kernel_map1[j*kernel_width + i];
+ }
+
+ if (total2 == 0)
+ total2 = 1;
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ value1 = 0;
+ value2 = 0;
+
+ for(y = -kh2; y <= kh2; y++)
+ {
+ if (j + y < 0) // pass the bottom border
+ offset = -(y + j + 1) * width;
+ else if (j + y >= height) // pass the top border
+ offset = (2*height - 1 - (j + y)) * width;
+ else
+ offset = (j + y) * width;
+
+ kernel_line = kernel_map1 + (y+kh2)*kernel_width;
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value1 += map[offset - (i + x + 1)] * (float)kernel_line[x+kw2];
+ else if (i + x >= width) // pass the right border
+ value1 += map[offset + 2*width - 1 - (i + x)] * (float)kernel_line[x+kw2];
+ else if (offset != -1)
+ value1 += map[offset + (i + x)] * (float)kernel_line[x+kw2];
+ }
+
+ kernel_line = kernel_map2 + (y+kh2)*kernel_width;
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value2 += map[offset - (i + x + 1)] * (float)kernel_line[x+kw2];
+ else if (i + x >= width) // pass the right border
+ value2 += map[offset + 2*width - 1 - (i + x)] * (float)kernel_line[x+kw2];
+ else if (offset != -1)
+ value2 += map[offset + (i + x)] * (float)kernel_line[x+kw2];
+ }
+ }
+
+ value1 /= (float)total1;
+ value2 /= (float)total2;
+
+ new_map[new_offset + i] = sqrt(value1*value1 + value2*value2);
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+int imProcessConvolveDual(const imImage* src_image, imImage* dst_image, const imImage *kernel1, const imImage *kernel2)
+{
+ int counter = imCounterBegin("Convolution");
+ const char* msg = (const char*)imImageGetAttribute(kernel1, "Description", NULL, NULL);
+ if (!msg) msg = "Filtering...";
+ imCounterTotal(counter, src_image->depth*src_image->height, msg);
+
+ int ret = 0;
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ if (kernel1->data_type == IM_INT)
+ ret = DoConvolveDual((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel1->data[0], (int*)kernel2->data[0], kernel1->width, kernel1->height, counter, (int)0);
+ else
+ ret = DoConvolveDual((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel1->data[0], (float*)kernel2->data[0], kernel1->width, kernel1->height, counter, (float)0);
+ break;
+ case IM_USHORT:
+ if (kernel1->data_type == IM_INT)
+ ret = DoConvolveDual((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel1->data[0], (int*)kernel2->data[0], kernel1->width, kernel1->height, counter, (int)0);
+ else
+ ret = DoConvolveDual((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel1->data[0], (float*)kernel2->data[0], kernel1->width, kernel1->height, counter, (float)0);
+ break;
+ case IM_INT:
+ if (kernel1->data_type == IM_INT)
+ ret = DoConvolveDual((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel1->data[0], (int*)kernel2->data[0], kernel1->width, kernel1->height, counter, (int)0);
+ else
+ ret = DoConvolveDual((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel1->data[0], (float*)kernel2->data[0], kernel1->width, kernel1->height, counter, (float)0);
+ break;
+ case IM_FLOAT:
+ if (kernel1->data_type == IM_INT)
+ ret = DoConvolveDual((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel1->data[0], (int*)kernel2->data[0], kernel1->width, kernel1->height, counter, (float)0);
+ else
+ ret = DoConvolveDual((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel1->data[0], (float*)kernel2->data[0], kernel1->width, kernel1->height, counter, (float)0);
+ break;
+ case IM_CFLOAT:
+ if (kernel1->data_type == IM_INT)
+ ret = DoConvolveDualCpx((imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel1->data[0], (int*)kernel2->data[0], kernel1->width, kernel1->height, counter);
+ else
+ ret = DoConvolveDualCpx((imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel1->data[0], (float*)kernel2->data[0], kernel1->width, kernel1->height, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+template <class T, class KT, class CT>
+static int DoConvolve(T* map, T* new_map, int width, int height, KT* kernel_map, int kernel_width, int kernel_height, int counter, CT)
+{
+ CT value;
+ KT total, *kernel_line;
+ int offset, new_offset, i, j, x, y;
+
+ int kh2 = kernel_height/2;
+ int kw2 = kernel_width/2;
+
+ if (kernel_height % 2 == 0) kh2--;
+ if (kernel_width % 2 == 0) kw2--;
+
+ total = 0;
+ for(j = 0; j < kernel_height; j++)
+ {
+ for(i = 0; i < kernel_width; i++)
+ total += kernel_map[j*kernel_width + i];
+ }
+
+ if (total == 0)
+ total = 1;
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ value = 0;
+
+ for(y = -kh2; y <= kh2; y++)
+ {
+ kernel_line = kernel_map + (y+kh2)*kernel_width;
+
+ if (j + y < 0) // pass the bottom border
+ offset = -(y + j + 1) * width;
+ else if (j + y >= height) // pass the top border
+ offset = (2*height - 1 - (j + y)) * width;
+ else
+ offset = (j + y) * width;
+
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value += kernel_line[x+kw2] * map[offset - (i + x + 1)];
+ else if (i + x >= width) // pass the right border
+ value += kernel_line[x+kw2] * map[offset + 2*width - 1 - (i + x)];
+ else if (offset != -1)
+ value += kernel_line[x+kw2] * map[offset + (i + x)];
+ }
+ }
+
+ value /= total;
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T) == size_of)
+ new_map[new_offset + i] = (T)IM_BYTECROP(value);
+ else
+ new_map[new_offset + i] = (T)value;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+template <class KT>
+static int DoConvolveCpx(imcfloat* map, imcfloat* new_map, int width, int height, KT* kernel_map, int kernel_width, int kernel_height, int counter)
+{
+ imcfloat value;
+ KT total, *kernel_line;
+ int offset, new_offset, i, j, x, y;
+
+ int kh2 = kernel_height/2;
+ int kw2 = kernel_width/2;
+
+ if (kernel_height % 2 == 0) kh2--;
+ if (kernel_width % 2 == 0) kw2--;
+
+ total = 0;
+ for(j = 0; j < kernel_height; j++)
+ {
+ for(i = 0; i < kernel_width; i++)
+ total += kernel_map[j*kernel_width + i];
+ }
+
+ if (total == 0)
+ total = 1;
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ value = 0;
+
+ for(y = -kh2; y <= kh2; y++)
+ {
+ kernel_line = kernel_map + (y+kh2)*kernel_width;
+
+ if (j + y < 0) // pass the bottom border
+ offset = -(y + j + 1) * width;
+ else if (j + y >= height) // pass the top border
+ offset = (2*height - 1 - (j + y)) * width;
+ else
+ offset = (j + y) * width;
+
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value += map[offset - (i + x + 1)] * (float)kernel_line[x+kw2];
+ else if (i + x >= width) // pass the right border
+ value += map[offset + 2*width - 1 - (i + x)] * (float)kernel_line[x+kw2];
+ else if (offset != -1)
+ value += map[offset + (i + x)] * (float)kernel_line[x+kw2];
+ }
+ }
+
+ value /= (float)total;
+
+ new_map[new_offset + i] = value;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int DoConvolveStep(const imImage* src_image, imImage* dst_image, const imImage *kernel, int counter)
+{
+ int ret = 0;
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolve((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (int)0);
+ else
+ ret = DoConvolve((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_USHORT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolve((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (int)0);
+ else
+ ret = DoConvolve((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_INT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolve((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (int)0);
+ else
+ ret = DoConvolve((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_FLOAT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolve((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ else
+ ret = DoConvolve((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_CFLOAT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolveCpx((imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter);
+ else
+ ret = DoConvolveCpx((imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ return ret;
+}
+
+int imProcessConvolve(const imImage* src_image, imImage* dst_image, const imImage *kernel)
+{
+ int counter = imCounterBegin("Convolution");
+ const char* msg = (const char*)imImageGetAttribute(kernel, "Description", NULL, NULL);
+ if (!msg) msg = "Filtering...";
+ imCounterTotal(counter, src_image->depth*src_image->height, msg);
+
+ int ret = DoConvolveStep(src_image, dst_image, kernel, counter);
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+int imProcessConvolveRep(const imImage* src_image, imImage* dst_image, const imImage *kernel, int ntimes)
+{
+ imImage *AuxImage = imImageClone(dst_image);
+ if (!AuxImage)
+ return 0;
+
+ int counter = imCounterBegin("Repeated Convolution");
+ const char* msg = (const char*)imImageGetAttribute(kernel, "Description", NULL, NULL);
+ if (!msg) msg = "Filtering...";
+ imCounterTotal(counter, src_image->depth*src_image->height*ntimes, msg);
+
+ const imImage *image1 = src_image;
+ imImage *image2 = dst_image;
+
+ for (int i = 0; i < ntimes; i++)
+ {
+ if (!DoConvolveStep(image1, image2, kernel, counter))
+ {
+ imCounterEnd(counter);
+ imImageDestroy(AuxImage);
+ return 0;
+ }
+
+ image1 = image2;
+
+ if (image1 == dst_image)
+ image2 = AuxImage;
+ else
+ image2 = dst_image;
+ }
+
+ // The result is in image1, if in the Aux swap the data
+ if (image1 == AuxImage)
+ {
+ void** temp = (void**)dst_image->data;
+ dst_image->data = AuxImage->data;
+ AuxImage->data = (void**)temp;
+ }
+
+ imCounterEnd(counter);
+ imImageDestroy(AuxImage);
+
+ return 1;
+}
+
+template <class T, class KT, class CT>
+static int DoConvolveSep(T* map, T* new_map, int width, int height, KT* kernel_map, int kernel_width, int kernel_height, int counter, CT)
+{
+ CT value;
+ KT totalV, totalH, *kernel_line;
+ T* aux_line;
+ int offset, new_offset, i, j;
+
+ int kh2 = kernel_height/2;
+ int kw2 = kernel_width/2;
+
+ if (kernel_height % 2 == 0) kh2--;
+ if (kernel_width % 2 == 0) kw2--;
+
+ // use only the first line and the first column of the kernel
+
+ totalV = 0;
+ for(j = 0; j < kernel_height; j++)
+ totalV += kernel_map[j*kernel_width];
+
+ if (totalV == 0)
+ totalV = 1;
+
+ totalH = 0;
+ for(i = 0; i < kernel_width; i++)
+ totalH += kernel_map[i];
+
+ if (totalH == 0)
+ totalH = 1;
+
+ aux_line = (T*)malloc(width*sizeof(T));
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ int y;
+ value = 0;
+
+ // first pass, only for columns
+
+ for(y = -kh2; y <= kh2; y++)
+ {
+ kernel_line = kernel_map + (y+kh2)*kernel_width;
+
+ if (j + y < 0) // pass the bottom border
+ offset = -(y + j + 1) * width;
+ else if (j + y >= height) // pass the top border
+ offset = (2*height - 1 - (j + y)) * width;
+ else
+ offset = (j + y) * width;
+
+ if (offset != -1)
+ value += kernel_line[0] * map[offset + i];
+ }
+
+ value /= totalV;
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T) == size_of)
+ new_map[new_offset + i] = (T)IM_BYTECROP(value);
+ else
+ new_map[new_offset + i] = (T)value;
+ }
+
+ if (!imCounterInc(counter))
+ {
+ free(aux_line);
+ return 0;
+ }
+ }
+
+ for(j = 0; j < height; j++)
+ {
+ offset = new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ int x;
+ value = 0;
+
+ // second pass, only for lines, but has to use an auxiliar buffer
+
+ kernel_line = kernel_map;
+
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value += kernel_line[x+kw2] * new_map[offset - (i + x + 1)];
+ else if (i + x >= width) // pass the right border
+ value += kernel_line[x+kw2] * new_map[offset + 2*width - 1 - (i + x)];
+ else
+ value += kernel_line[x+kw2] * new_map[offset + (i + x)];
+ }
+
+ value /= totalH;
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T) == size_of)
+ aux_line[i] = (T)IM_BYTECROP(value);
+ else
+ aux_line[i] = (T)value;
+ }
+
+ memcpy(new_map + new_offset, aux_line, width*sizeof(T));
+
+ if (!imCounterInc(counter))
+ {
+ free(aux_line);
+ return 0;
+ }
+ }
+
+ free(aux_line);
+ return 1;
+}
+
+
+template <class KT>
+static int DoConvolveSepCpx(imcfloat* map, imcfloat* new_map, int width, int height, KT* kernel_map, int kernel_width, int kernel_height, int counter)
+{
+ imcfloat value;
+ KT totalV, totalH, *kernel_line;
+ imcfloat* aux_line;
+ int offset, new_offset, i, j;
+
+ int kh2 = kernel_height/2;
+ int kw2 = kernel_width/2;
+
+ if (kernel_height % 2 == 0) kh2--;
+ if (kernel_width % 2 == 0) kw2--;
+
+ // use only the first line and the first column of the kernel
+
+ totalV = 0;
+ for(j = 0; j < kernel_height; j++)
+ totalV += kernel_map[j*kernel_width];
+
+ if (totalV == 0)
+ totalV = 1;
+
+ totalH = 0;
+ for(i = 0; i < kernel_width; i++)
+ totalH += kernel_map[i];
+
+ if (totalH == 0)
+ totalH = 1;
+
+ aux_line = (imcfloat*)malloc(width*sizeof(imcfloat));
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ int y;
+ value = 0;
+
+ // first pass, only for columns
+
+ for(y = -kh2; y <= kh2; y++)
+ {
+ kernel_line = kernel_map + (y+kh2)*kernel_width;
+
+ if (j + y < 0) // pass the bottom border
+ offset = -(y + j + 1) * width;
+ else if (j + y >= height) // pass the top border
+ offset = (2*height - 1 - (j + y)) * width;
+ else
+ offset = (j + y) * width;
+
+ if (offset != -1)
+ value += map[offset + i] * (float)kernel_line[0];
+ }
+
+ value /= (float)totalV;
+
+ new_map[new_offset + i] = value;
+ }
+
+ if (!imCounterInc(counter))
+ {
+ free(aux_line);
+ return 0;
+ }
+ }
+
+ for(j = 0; j < height; j++)
+ {
+ offset = new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ int x;
+ value = 0;
+
+ // second pass, only for lines, but has to use an auxiliar buffer
+
+ kernel_line = kernel_map;
+
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (i + x < 0) // pass the left border
+ value += new_map[offset - (i + x + 1)] * (float)kernel_line[x+kw2];
+ else if (i + x >= width) // pass the right border
+ value += new_map[offset + 2*width - 1 - (i + x)] * (float)kernel_line[x+kw2];
+ else if (offset != -1)
+ value += new_map[offset + (i + x)] * (float)kernel_line[x+kw2];
+ }
+
+ value /= (float)totalH;
+
+ aux_line[i] = value;
+ }
+
+ memcpy(new_map + new_offset, aux_line, width*sizeof(imcfloat));
+
+ if (!imCounterInc(counter))
+ {
+ free(aux_line);
+ return 0;
+ }
+ }
+
+ free(aux_line);
+ return 1;
+}
+
+int imProcessConvolveSep(const imImage* src_image, imImage* dst_image, const imImage *kernel)
+{
+ int counter = imCounterBegin("Separable Convolution");
+ const char* msg = (const char*)imImageGetAttribute(kernel, "Description", NULL, NULL);
+ if (!msg) msg = "Filtering...";
+ imCounterTotal(counter, 2*src_image->depth*src_image->height, msg);
+
+ int ret = 0;
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolveSep((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (int)0);
+ else
+ ret = DoConvolveSep((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_USHORT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolveSep((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (int)0);
+ else
+ ret = DoConvolveSep((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_INT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolveSep((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (int)0);
+ else
+ ret = DoConvolveSep((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_FLOAT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolveSep((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ else
+ ret = DoConvolveSep((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter, (float)0);
+ break;
+ case IM_CFLOAT:
+ if (kernel->data_type == IM_INT)
+ ret = DoConvolveSepCpx((imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], src_image->width, src_image->height, (int*)kernel->data[0], kernel->width, kernel->height, counter);
+ else
+ ret = DoConvolveSepCpx((imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], src_image->width, src_image->height, (float*)kernel->data[0], kernel->width, kernel->height, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+/*
+Description:
+ Can be used to find zero crossing of second derivative,
+ laplace. Can also be used to determine any other kind
+ of crossing. Pixels below or equal to 't' are set if the pixel
+ to the right or below is above 't', pixels above 't' are
+ set if the pixel to the right or below is below or equal to
+ 't'. Pixels that are "set" are set to the maximum absolute
+ difference of the two neighbours, to indicate the strength
+ of the edge.
+
+ | IF (crossing t)
+ | out(x,y) = MAX(ABS(in(x,y)-in(x+1,y)), ABS(in(x,y)-in(x,y+1)))
+ | ELSE
+ | out(x,y) = 0
+
+Author: Tor Lønnestad, BLAB, Ifi, UiO
+
+Copyright 1991, Blab, UiO
+Image processing lab, Department of Informatics
+University of Oslo
+*/
+template <class T>
+static void do_crossing(T* iband, T* oband, int width, int height, T t)
+{
+ int x, y, offset00 = 0, offset10 = 0, offset01 = 0;
+ T v, diff;
+
+ for (y=0; y < height-1; y++)
+ {
+ offset00 = y*width;
+ offset10 = (y+1)*width;
+ offset01 = offset00 + 1;
+
+ for (x=0; x < width-1; x++)
+ {
+ v = 0;
+
+ if (iband[offset00] <= t)
+ {
+ if (iband[offset10] > t)
+ v = iband[offset10]-iband[offset00];
+
+ if (iband[offset01] > t)
+ {
+ diff = iband[offset01]-iband[offset00];
+ if (diff > v) v = diff;
+ }
+ }
+ else
+ {
+ if (iband[offset10] <= t)
+ v = iband[offset00]-iband[offset10];
+
+ if (iband[offset01] <= t)
+ {
+ diff = iband[offset00]-iband[offset01];
+ if (diff > v) v = diff;
+ }
+ }
+
+ oband[offset00] = v;
+
+ offset00++;
+ offset10++;
+ offset01++;
+ }
+
+ /* last pixel on line */
+ offset00++;
+ offset10++;
+
+ v = 0;
+
+ if (iband[offset00] <= t)
+ {
+ if (iband[offset10] > t)
+ v = iband[offset10]-iband[offset00];
+ }
+ else
+ {
+ if (iband[offset10] <= t)
+ v = iband[offset00]-iband[offset10];
+ }
+
+ oband[offset00] = v;
+ }
+
+ /* last line */
+ offset00 = y*width;
+ offset01 = offset00 + 1;
+
+ for (x=0; x < width-1; x++)
+ {
+ v = 0;
+
+ if (iband[offset00] <= t)
+ {
+ if (iband[offset01] > t)
+ v = iband[offset01]-iband[offset00];
+ }
+ else
+ {
+ if (iband[offset01] <= t)
+ v = iband[offset00]-iband[offset01];
+ }
+
+ oband[offset00] = v;
+
+ offset00++;
+ offset01++;
+ }
+
+ offset00++;
+
+ /* last pixel */
+ oband[offset00] = 0;
+}
+
+void imProcessZeroCrossing(const imImage* src_image, imImage* dst_image)
+{
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_INT:
+ do_crossing((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, 0);
+ break;
+ case IM_FLOAT:
+ do_crossing((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, 0.0f);
+ break;
+ }
+ }
+}
+
+int imProcessBarlettConvolve(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_INT);
+ if (!kernel)
+ return 0;
+
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Barlett");
+
+ int* kernel_data = (int*)kernel->data[0];
+ int half = kernel_size / 2;
+ for (int i = 0; i < kernel_size; i++)
+ {
+ if (i <= half)
+ kernel_data[i] = i+1;
+ else
+ kernel_data[i] = kernel_size-i;
+ }
+ for (int j = 0; j < kernel_size; j++)
+ {
+ if (j <= half)
+ kernel_data[j*kernel_size] = j+1;
+ else
+ kernel_data[j*kernel_size] = kernel_size-j;
+ }
+
+ int ret = imProcessConvolveSep(src_image, dst_image, kernel);
+
+ imImageDestroy(kernel);
+
+ return ret;
+}
+
+int imProcessSobelConvolve(const imImage* src_image, imImage* dst_image)
+{
+ int ret = 0;
+
+ imImage* kernel1 = imKernelSobel();
+ imImage* kernel2 = imImageCreate(3, 3, IM_GRAY, IM_INT);
+ imProcessRotate90(kernel1, kernel2, 1);
+
+ ret = imProcessConvolveDual(src_image, dst_image, kernel1, kernel2);
+
+ imImageDestroy(kernel1);
+ imImageDestroy(kernel2);
+
+ return ret;
+}
+
+int imProcessPrewittConvolve(const imImage* src_image, imImage* dst_image)
+{
+ int ret = 0;
+
+ imImage* kernel1 = imKernelPrewitt();
+ imImage* kernel2 = imImageClone(kernel1);
+ imProcessRotate90(kernel1, kernel2, 1);
+
+ ret = imProcessConvolveDual(src_image, dst_image, kernel1, kernel2);
+
+ imImageDestroy(kernel1);
+ imImageDestroy(kernel2);
+
+ return ret;
+}
+
+int imProcessSplineEdgeConvolve(const imImage* src_image, imImage* dst_image)
+{
+ int ret = 0;
+
+ imImage* tmp_image = imImageClone(src_image);
+ if (!tmp_image) return 0;
+
+ imImage* kernel1 = imImageCreate(5, 5, IM_GRAY, IM_INT);
+ imImageSetAttribute(kernel1, "Description", IM_BYTE, -1, (void*)"SplineEdge");
+
+ int* kernel_data = (int*)kernel1->data[0];
+ kernel_data[10] = -1;
+ kernel_data[11] = 8;
+ kernel_data[12] = 0;
+ kernel_data[13] = -8;
+ kernel_data[14] = 1;
+
+ imImage* kernel2 = imImageClone(kernel1);
+ imProcessRotate90(kernel1, kernel2, 1);
+
+ imImage* kernel3 = imImageClone(kernel1);
+ imProcessRotateKernel(kernel3);
+
+ imImage* kernel4 = imImageClone(kernel1);
+ imProcessRotate90(kernel3, kernel4, 1);
+
+ ret = imProcessConvolveDual(src_image, tmp_image, kernel1, kernel2);
+ ret = imProcessConvolveDual(src_image, dst_image, kernel3, kernel4);
+
+ imProcessArithmeticConstOp(tmp_image, (float)sqrt(2.0), tmp_image, IM_BIN_MUL);
+ imProcessArithmeticOp(tmp_image, dst_image, dst_image, IM_BIN_ADD);
+
+ imImageDestroy(kernel1);
+ imImageDestroy(kernel2);
+ imImageDestroy(kernel3);
+ imImageDestroy(kernel4);
+ imImageDestroy(tmp_image);
+
+ return ret;
+}
+
+int imGaussianStdDev2KernelSize(float stddev)
+{
+ if (stddev < 0)
+ return (int)-stddev;
+ else
+ {
+ int width = (int)(3.35*stddev + 0.3333);
+ return 2*width + 1;
+ }
+}
+
+float imGaussianKernelSize2StdDev(int kernel_size)
+{
+ int width = (kernel_size - 1)/2;
+ return (width - 0.3333f)/3.35f;
+}
+
+int imProcessGaussianConvolve(const imImage* src_image, imImage* dst_image, float stddev)
+{
+ int kernel_size = imGaussianStdDev2KernelSize(stddev);
+
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_FLOAT);
+ if (!kernel)
+ return 0;
+
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Gaussian");
+ imProcessRenderGaussian(kernel, stddev);
+
+ int ret = imProcessConvolveSep(src_image, dst_image, kernel);
+
+ imImageDestroy(kernel);
+
+ return ret;
+}
+
+int imProcessLapOfGaussianConvolve(const imImage* src_image, imImage* dst_image, float stddev)
+{
+ int kernel_size = imGaussianStdDev2KernelSize(stddev);
+
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_FLOAT);
+ if (!kernel)
+ return 0;
+
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Laplacian Of Gaussian");
+ imProcessRenderLapOfGaussian(kernel, stddev);
+
+ int ret;
+ if (src_image->data_type == IM_BYTE || src_image->data_type == IM_USHORT)
+ {
+ imImage* aux_image = imImageClone(dst_image);
+ if (!aux_image)
+ {
+ imImageDestroy(kernel);
+ return 0;
+ }
+
+ imProcessUnArithmeticOp(src_image, aux_image, IM_UN_EQL); // Convert to IM_INT
+ ret = imProcessConvolve(aux_image, dst_image, kernel);
+ imImageDestroy(aux_image);
+ }
+ else
+ ret = imProcessConvolve(src_image, dst_image, kernel);
+
+ imImageDestroy(kernel);
+
+ return ret;
+}
+
+int imProcessDiffOfGaussianConvolve(const imImage* src_image, imImage* dst_image, float stddev1, float stddev2)
+{
+ imImage* aux_image1 = imImageClone(src_image);
+ imImage* aux_image2 = imImageClone(src_image);
+ if (!aux_image1 || !aux_image2)
+ {
+ if (aux_image1) imImageDestroy(aux_image1);
+ return 0;
+ }
+
+ int kernel_size1 = imGaussianStdDev2KernelSize(stddev1);
+ int kernel_size2 = imGaussianStdDev2KernelSize(stddev2);
+ int size = kernel_size1;
+ if (kernel_size1 < kernel_size2) size = kernel_size2;
+
+ imImage* kernel1 = imImageCreate(size, size, IM_GRAY, IM_FLOAT);
+ imImage* kernel2 = imImageCreate(size, size, IM_GRAY, IM_FLOAT);
+ if (!kernel1 || !kernel2)
+ {
+ if (kernel1) imImageDestroy(kernel1);
+ if (kernel2) imImageDestroy(kernel2);
+ imImageDestroy(aux_image1);
+ imImageDestroy(aux_image2);
+ return 0;
+ }
+
+ imImageSetAttribute(kernel1, "Description", IM_BYTE, -1, (void*)"Gaussian1");
+ imImageSetAttribute(kernel2, "Description", IM_BYTE, -1, (void*)"Gaussian2");
+
+ imProcessRenderGaussian(kernel1, stddev1);
+ imProcessRenderGaussian(kernel2, stddev2);
+
+ if (!imProcessConvolve(src_image, aux_image1, kernel1) ||
+ !imProcessConvolve(src_image, aux_image2, kernel2))
+ {
+ imImageDestroy(kernel1);
+ imImageDestroy(kernel2);
+ imImageDestroy(aux_image1);
+ imImageDestroy(aux_image2);
+ return 0;
+ }
+
+ imProcessArithmeticOp(aux_image1, aux_image2, dst_image, IM_BIN_SUB);
+
+ imImageDestroy(kernel1);
+ imImageDestroy(kernel2);
+ imImageDestroy(aux_image1);
+ imImageDestroy(aux_image2);
+
+ return 1;
+}
+
+int imProcessMeanConvolve(const imImage* src_image, imImage* dst_image, int ks)
+{
+ int counter = imCounterBegin("Mean Convolve");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ imImage* kernel = imImageCreate(ks, ks, IM_GRAY, IM_INT);
+
+ int* kernel_data = (int*)kernel->data[0];
+
+ int ks2 = ks/2;
+ for(int ky = 0; ky < ks; ky++)
+ {
+ int ky2 = ky-ks2;
+ ky2 = ky2*ky2;
+ for(int kx = 0; kx < ks; kx++)
+ {
+ int kx2 = kx-ks2;
+ kx2 = kx2*kx2;
+ int radius = imRound(sqrt(double(kx2 + ky2)));
+ if (radius <= ks2)
+ kernel_data[ky*ks + kx] = 1;
+ }
+ }
+
+ int ret = DoConvolveStep(src_image, dst_image, kernel, counter);
+
+ imImageDestroy(kernel);
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+template <class T1, class T2>
+static void DoSharpOp(T1 *src_map, T1 *dst_map, int count, float amount, T2 threshold, int gauss)
+{
+ int i;
+ T1 min, max;
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T1) == size_of)
+ {
+ min = 0;
+ max = 255;
+ }
+ else
+ {
+ imMinMax(src_map, count, min, max);
+
+ if (min == max)
+ {
+ max = min + 1;
+
+ if (min != 0)
+ min = min - 1;
+ }
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ T2 diff;
+
+ if (gauss)
+ diff = 20*(src_map[i] - dst_map[i]); /* dst_map contains a gaussian filter of the source image, must compensate for small edge values */
+ else
+ diff = dst_map[i]; /* dst_map contains a laplacian filter of the source image */
+
+ if (threshold && abs_op(2*diff) < threshold)
+ diff = 0;
+
+ T2 value = (T2)(src_map[i] + amount*diff);
+ if (value < min)
+ value = min;
+ else if (value > max)
+ value = max;
+
+ dst_map[i] = (T1)value;
+ }
+}
+
+static void doSharp(const imImage* src_image, imImage* dst_image, float amount, float threshold, int gauss)
+{
+ int count = src_image->count;
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ DoSharpOp((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], count, amount, (int)threshold, gauss);
+ break;
+ case IM_USHORT:
+ DoSharpOp((imushort*)src_image->data[i], (imushort*)dst_image->data[i], count, amount, (int)threshold, gauss);
+ break;
+ case IM_INT:
+ DoSharpOp((int*)src_image->data[i], (int*)dst_image->data[i], count, amount, (int)threshold, gauss);
+ break;
+ case IM_FLOAT:
+ DoSharpOp((float*)src_image->data[i], (float*)dst_image->data[i], count, amount, (float)threshold, gauss);
+ break;
+ }
+ }
+}
+
+int imProcessUnsharp(const imImage* src_image, imImage* dst_image, float stddev, float amount, float threshold)
+{
+ int kernel_size = imGaussianStdDev2KernelSize(stddev);
+
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_FLOAT);
+ if (!kernel)
+ return 0;
+
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Unsharp");
+ imProcessRenderGaussian(kernel, stddev);
+
+ int ret = imProcessConvolveSep(src_image, dst_image, kernel);
+ doSharp(src_image, dst_image, amount, threshold, 1);
+
+ imImageDestroy(kernel);
+
+ return ret;
+}
+
+int imProcessSharp(const imImage* src_image, imImage* dst_image, float amount, float threshold)
+{
+ imImage* kernel = imKernelLaplacian8();
+ if (!kernel)
+ return 0;
+
+ int ret = imProcessConvolve(src_image, dst_image, kernel);
+ doSharp(src_image, dst_image, amount, threshold, 0);
+
+ imImageDestroy(kernel);
+
+ return ret;
+}
+
+static int iProcessCheckKernelType(const imImage* kernel)
+{
+ if (kernel->data_type == IM_INT)
+ {
+ int* kernel_data = (int*)kernel->data[0];
+ for (int i = 0; i < kernel->count; i++)
+ {
+ if (kernel_data[i] < 0) /* if there are negative values, assume kernel is an edge detector */
+ return 0;
+ }
+ }
+ else if (kernel->data_type == IM_FLOAT)
+ {
+ float* kernel_data = (float*)kernel->data[0];
+ for (int i = 0; i < kernel->count; i++)
+ {
+ if (kernel_data[i] < 0) /* if there are negative values, assume kernel is an edge detector */
+ return 0;
+ }
+ }
+ return 1; /* default is kernel is a smooth filter */
+}
+
+int imProcessSharpKernel(const imImage* src_image, const imImage* kernel, imImage* dst_image, float amount, float threshold)
+{
+ int ret = imProcessConvolve(src_image, dst_image, kernel);
+ doSharp(src_image, dst_image, amount, threshold, iProcessCheckKernelType(kernel));
+ return ret;
+}
+
diff --git a/im/src/process/im_convolve_rank.cpp b/im/src/process/im_convolve_rank.cpp
new file mode 100755
index 0000000..5488a78
--- /dev/null
+++ b/im/src/process/im_convolve_rank.cpp
@@ -0,0 +1,701 @@
+/** \file
+ * \brief Rank Convolution Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_convolve_rank.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_counter.h>
+#include <im_math.h>
+
+#include "im_process_loc.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+#include <math.h>
+
+
+template <class T, class DT>
+static int DoConvolveRankFunc(T *map, DT* new_map, int width, int height, int kw, int kh, T (*func)(T* value, int count, int center), int counter)
+{
+ T* value = new T[kw*kh];
+ int offset, new_offset, i, j, x, y, v, c;
+ int kh1, kw1, kh2, kw2;
+
+ kh2 = kh/2;
+ kw2 = kw/2;
+ kh1 = -kh2;
+ kw1 = -kw2;
+ if (kh%2==0) kh2--; // if not odd decrease 1
+ if (kw%2==0) kw2--;
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ v = 0; c = 0;
+
+ for(y = kh1; y <= kh2; y++)
+ {
+ if ((j + y < 0) || // pass the bottom border
+ (j + y >= height)) // pass the top border
+ continue;
+
+ offset = (j + y) * width;
+
+ for(x = kw1; x <= kw2; x++)
+ {
+ if ((i + x < 0) || // pass the left border
+ (i + x >= width)) // pass the right border
+ continue;
+
+ if (x == 0 && y == 0)
+ c = v;
+
+ value[v] = map[offset + (i + x)];
+ v++;
+ }
+ }
+
+ new_map[new_offset + i] = (DT)func(value, v, c);
+ }
+
+ if (!imCounterInc(counter))
+ {
+ delete[] value;
+ return 0;
+ }
+ }
+
+ delete[] value;
+ return 1;
+}
+
+static int compare_imReal(const void *elem1, const void *elem2)
+{
+ float* v1 = (float*)elem1;
+ float* v2 = (float*)elem2;
+
+ if (*v1 < *v2)
+ return -1;
+
+ if (*v1 > *v2)
+ return 1;
+
+ return 0;
+}
+
+static int compare_imInt(const void *elem1, const void *elem2)
+{
+ int* v1 = (int*)elem1;
+ int* v2 = (int*)elem2;
+
+ if (*v1 < *v2)
+ return -1;
+
+ if (*v1 > *v2)
+ return 1;
+
+ return 0;
+}
+
+static int compare_imUShort(const void *elem1, const void *elem2)
+{
+ imushort* v1 = (imushort*)elem1;
+ imushort* v2 = (imushort*)elem2;
+
+ if (*v1 < *v2)
+ return -1;
+
+ if (*v1 > *v2)
+ return 1;
+
+ return 0;
+}
+
+static int compare_imByte(const void *elem1, const void *elem2)
+{
+ imbyte* v1 = (imbyte*)elem1;
+ imbyte* v2 = (imbyte*)elem2;
+
+ if (*v1 < *v2)
+ return -1;
+
+ if (*v1 > *v2)
+ return 1;
+
+ return 0;
+}
+
+static imbyte median_op_byte(imbyte* value, int count, int center)
+{
+ (void)center;
+ qsort(value, count, sizeof(imbyte), compare_imByte);
+ return value[count/2];
+}
+
+static imushort median_op_ushort(imushort* value, int count, int center)
+{
+ (void)center;
+ qsort(value, count, sizeof(imushort), compare_imUShort);
+ return value[count/2];
+}
+
+static int median_op_int(int* value, int count, int center)
+{
+ (void)center;
+ qsort(value, count, sizeof(int), compare_imInt);
+ return value[count/2];
+}
+
+static float median_op_real(float* value, int count, int center)
+{
+ (void)center;
+ qsort(value, count, sizeof(float), compare_imReal);
+ return value[count/2];
+}
+
+int imProcessMedianConvolve(const imImage* src_image, imImage* dst_image, int ks)
+{
+ int i, ret = 0;
+ int counter;
+
+ counter = imCounterBegin("Median Filter");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoConvolveRankFunc((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, median_op_byte, counter);
+ break;
+ case IM_USHORT:
+ ret = DoConvolveRankFunc((imushort*)src_image->data[i], (imushort*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, median_op_ushort, counter);
+ break;
+ case IM_INT:
+ ret = DoConvolveRankFunc((int*)src_image->data[i], (int*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, median_op_int, counter);
+ break;
+ case IM_FLOAT:
+ ret = DoConvolveRankFunc((float*)src_image->data[i], (float*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, median_op_real, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static imbyte range_op_byte(imbyte* value, int count, int center)
+{
+ imbyte min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max-min;
+}
+
+static imushort range_op_ushort(imushort* value, int count, int center)
+{
+ imushort min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max-min;
+}
+
+static int range_op_int(int* value, int count, int center)
+{
+ int min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max-min;
+}
+
+static float range_op_real(float* value, int count, int center)
+{
+ float min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max-min;
+}
+
+int imProcessRangeConvolve(const imImage* src_image, imImage* dst_image, int ks)
+{
+ int i, ret = 0;
+ int counter;
+
+ counter = imCounterBegin("Range Filter");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoConvolveRankFunc((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, range_op_byte, counter);
+ break;
+ case IM_USHORT:
+ ret = DoConvolveRankFunc((imushort*)src_image->data[i], (imushort*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, range_op_ushort, counter);
+ break;
+ case IM_INT:
+ ret = DoConvolveRankFunc((int*)src_image->data[i], (int*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, range_op_int, counter);
+ break;
+ case IM_FLOAT:
+ ret = DoConvolveRankFunc((float*)src_image->data[i], (float*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, range_op_real, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+/*
+Local variable threshold by the method of Bernsen.
+
+Description:
+ If the difference between the largest and the smallest
+ pixel value within the 'dx'*'dy' window is greater than
+ or equal to 'cmin' (local contrast threshold), the average
+ of the two values is used as threshold.
+
+ Pixels in homogenous areas (difference below 'cmin')
+ are assumed to be below the threshold.
+
+Reference:
+ Bernsen, J: "Dynamic thresholding of grey-level images"
+ Proc. of the 8th ICPR, Paris, Oct 1986, 1251-1255.
+
+Author: Oivind Due Trier
+
+Copyright 1990, Blab, UiO
+Image processing lab, Department of Informatics
+University of Oslo
+*/
+
+static int thresAux = 0;
+
+static imbyte contrast_thres_op_byte(imbyte* value, int count, int center)
+{
+ int c, t;
+ imbyte v = value[center], min, max;
+
+ imMinMax(value, count, min, max);
+
+ c = max-min;
+
+ if (c < thresAux)
+ return 0;
+ else
+ {
+ t = ((int)max + (int)min) / 2;
+
+ if (v >= t)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+static imushort contrast_thres_op_ushort(imushort* value, int count, int center)
+{
+ int c, t;
+ imushort v = value[center], min, max;
+
+ imMinMax(value, count, min, max);
+
+ c = max-min;
+
+ if (c < thresAux)
+ return 0;
+ else
+ {
+ t = ((int)max + (int)min) / 2;
+
+ if (v >= t)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+static int contrast_thres_op_int(int* value, int count, int center)
+{
+ int c, t;
+ int v = value[center], min, max;
+
+ imMinMax(value, count, min, max);
+
+ c = max-min;
+
+ if (c < thresAux)
+ return 0;
+ else
+ {
+ t = ((int)max + (int)min) / 2;
+
+ if (v >= t)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+int imProcessRangeContrastThreshold(const imImage* src_image, imImage* dst_image, int ks, int min_range)
+{
+ int ret = 0;
+ int counter = imCounterBegin("Range Contrast Threshold");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ thresAux = min_range;
+
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoConvolveRankFunc((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->width, src_image->height, ks, ks, contrast_thres_op_byte, counter);
+ break;
+ case IM_USHORT:
+ ret = DoConvolveRankFunc((imushort*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->width, src_image->height, ks, ks, contrast_thres_op_ushort, counter);
+ break;
+ case IM_INT:
+ ret = DoConvolveRankFunc((int*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->width, src_image->height, ks, ks, contrast_thres_op_int, counter);
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static imbyte max_thres_op_byte(imbyte* value, int count, int center)
+{
+ imbyte v = value[center], min, max;
+
+ if (v < thresAux)
+ return 0;
+
+ imMinMax(value, count, min, max);
+
+ if (v < max)
+ return 0;
+
+ return 1;
+}
+
+static imushort max_thres_op_ushort(imushort* value, int count, int center)
+{
+ imushort v = value[center], min, max;
+
+ if (v < thresAux)
+ return 0;
+
+ imMinMax(value, count, min, max);
+
+ if (v < max)
+ return 0;
+
+ return 1;
+}
+
+static int max_thres_op_int(int* value, int count, int center)
+{
+ int v = value[center], min, max;
+
+ if (v < thresAux)
+ return 0;
+
+ imMinMax(value, count, min, max);
+
+ if (v < max)
+ return 0;
+
+ return 1;
+}
+
+int imProcessLocalMaxThreshold(const imImage* src_image, imImage* dst_image, int ks, int min_thres)
+{
+ int ret = 0;
+ int counter = imCounterBegin("Local Max Threshold");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ thresAux = min_thres;
+
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoConvolveRankFunc((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->width, src_image->height, ks, ks, max_thres_op_byte, counter);
+ break;
+ case IM_USHORT:
+ ret = DoConvolveRankFunc((imushort*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->width, src_image->height, ks, ks, max_thres_op_ushort, counter);
+ break;
+ case IM_INT:
+ ret = DoConvolveRankFunc((int*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->width, src_image->height, ks, ks, max_thres_op_int, counter);
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static imbyte rank_closest_op_byte(imbyte* value, int count, int center)
+{
+ imbyte v = value[center];
+ imbyte min, max;
+
+ imMinMax(value, count, min, max);
+
+ if (v - min < max - v)
+ return min;
+ else
+ return max;
+}
+
+static imushort rank_closest_op_ushort(imushort* value, int count, int center)
+{
+ imushort v = value[center];
+ imushort min, max;
+
+ imMinMax(value, count, min, max);
+
+ if (v - min < max - v)
+ return min;
+ else
+ return max;
+}
+
+static int rank_closest_op_int(int* value, int count, int center)
+{
+ int v = value[center];
+ int min, max;
+
+ imMinMax(value, count, min, max);
+
+ if (v - min < max - v)
+ return min;
+ else
+ return max;
+}
+
+static float rank_closest_op_real(float* value, int count, int center)
+{
+ float v = value[center];
+ float min, max;
+
+ imMinMax(value, count, min, max);
+
+ if (v - min < max - v)
+ return min;
+ else
+ return max;
+}
+
+
+int imProcessRankClosestConvolve(const imImage* src_image, imImage* dst_image, int ks)
+{
+ int i, ret = 0;
+ int counter;
+
+ counter = imCounterBegin("Rank Closest");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoConvolveRankFunc((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_closest_op_byte, counter);
+ break;
+ case IM_USHORT:
+ ret = DoConvolveRankFunc((imushort*)src_image->data[i], (imushort*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_closest_op_ushort, counter);
+ break;
+ case IM_INT:
+ ret = DoConvolveRankFunc((int*)src_image->data[i], (int*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_closest_op_int, counter);
+ break;
+ case IM_FLOAT:
+ ret = DoConvolveRankFunc((float*)src_image->data[i], (float*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_closest_op_real, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static imbyte rank_max_op_byte(imbyte* value, int count, int center)
+{
+ imbyte min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max;
+}
+
+static imushort rank_max_op_ushort(imushort* value, int count, int center)
+{
+ imushort min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max;
+}
+
+static int rank_max_op_int(int* value, int count, int center)
+{
+ int min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max;
+}
+
+static float rank_max_op_real(float* value, int count, int center)
+{
+ float min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return max;
+}
+
+int imProcessRankMaxConvolve(const imImage* src_image, imImage* dst_image, int ks)
+{
+ int i, ret = 0;
+ int counter;
+
+ counter = imCounterBegin("Rank Max");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoConvolveRankFunc((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_max_op_byte, counter);
+ break;
+ case IM_USHORT:
+ ret = DoConvolveRankFunc((imushort*)src_image->data[i], (imushort*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_max_op_ushort, counter);
+ break;
+ case IM_INT:
+ ret = DoConvolveRankFunc((int*)src_image->data[i], (int*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_max_op_int, counter);
+ break;
+ case IM_FLOAT:
+ ret = DoConvolveRankFunc((float*)src_image->data[i], (float*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_max_op_real, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static imbyte rank_min_op_byte(imbyte* value, int count, int center)
+{
+ imbyte min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return min;
+}
+
+static imushort rank_min_op_ushort(imushort* value, int count, int center)
+{
+ imushort min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return min;
+}
+
+static int rank_min_op_int(int* value, int count, int center)
+{
+ int min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return min;
+}
+
+static float rank_min_op_real(float* value, int count, int center)
+{
+ float min, max;
+ (void)center;
+ imMinMax(value, count, min, max);
+ return min;
+}
+
+int imProcessRankMinConvolve(const imImage* src_image, imImage* dst_image, int ks)
+{
+ int i, ret = 0;
+ int counter;
+
+ counter = imCounterBegin("Rank Min");
+ imCounterTotal(counter, src_image->depth*src_image->height, "Filtering...");
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoConvolveRankFunc((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_min_op_byte, counter);
+ break;
+ case IM_USHORT:
+ ret = DoConvolveRankFunc((imushort*)src_image->data[i], (imushort*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_min_op_ushort, counter);
+ break;
+ case IM_INT:
+ ret = DoConvolveRankFunc((int*)src_image->data[i], (int*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_min_op_int, counter);
+ break;
+ case IM_FLOAT:
+ ret = DoConvolveRankFunc((float*)src_image->data[i], (float*)dst_image->data[i],
+ src_image->width, src_image->height, ks, ks, rank_min_op_real, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
diff --git a/im/src/process/im_distance.cpp b/im/src/process/im_distance.cpp
new file mode 100755
index 0000000..019356d
--- /dev/null
+++ b/im/src/process/im_distance.cpp
@@ -0,0 +1,512 @@
+/** \file
+ * \brief Distance Transform
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_distance.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+#include <im.h>
+#include <im_util.h>
+
+#include "im_process_glo.h"
+
+#include <stdlib.h>
+#include <memory.h>
+#include <math.h>
+
+const float DT_ONE = 1.0f; // 1x0
+const float DT_SQRT2 = 1.414213562373f; // 1x1
+const float DT_SQRT5 = 2.2360679775f; // 2x1
+const float DT_SQRT10 = 3.1622776601684f; // 3x1
+const float DT_SQRT13 = 3.605551275464f; // 3x2
+const float DT_SQRT17 = 4.12310562562f; // 4x1
+const float DT_SQRT25 = 5.0f; // 4x3
+
+static inline void setValue(int r, int r1, int r2, int r3, int r4, float *image_data, int f)
+{
+ float v;
+ float minv = image_data[r]; // (x,y)
+
+ if (f)
+ v = image_data[r - 1] + DT_ONE; // (x-1,y)
+ else
+ v = image_data[r + 1] + DT_ONE; // (x+1,y)
+ if (v < minv) minv = v;
+
+ v = image_data[r1] + DT_ONE; // (x,y-1) (x,y+1)
+ if (v < minv) minv = v;
+
+ if (minv < DT_SQRT2)
+ goto min_attrib;
+
+ v = image_data[r1 - 1] + DT_SQRT2; // (x-1,y-1) (x-1,y+1)
+ if (v < minv) minv = v;
+
+ v = image_data[r1 + 1] + DT_SQRT2; // (x+1,y-1) (x+1,y+1)
+ if (v < minv) minv = v;
+
+ if (minv < DT_SQRT5)
+ goto min_attrib;
+
+ v = image_data[r1 + 2] + DT_SQRT5; // (x+2,y-1) (x+2,y+1)
+ if (v < minv) minv = v;
+
+ v = image_data[r1 - 2] + DT_SQRT5; // (x-2,y-1) (x-2,y+1)
+ if (v < minv) minv = v;
+
+ v = image_data[r2 - 1] + DT_SQRT5; // (x-1,y-2) (x-1,y+2)
+ if (v < minv) minv = v;
+
+ v = image_data[r2 + 1] + DT_SQRT5; // (x+1,y-2) (x+1,y+2)
+ if (v < minv) minv = v;
+
+ if (minv < DT_SQRT10)
+ goto min_attrib;
+
+ v = image_data[r1 + 3] + DT_SQRT10; // (x+3,y-1) (x+3,y+1)
+ if (v < minv) minv = v;
+
+ v = image_data[r1 - 3] + DT_SQRT10; // (x-3,y-1) (x-3,y+1)
+ if (v < minv) minv = v;
+
+ v = image_data[r3 - 1] + DT_SQRT10; // (x-1,y-3) (x-1,y+3)
+ if (v < minv) minv = v;
+
+ v = image_data[r3 + 1] + DT_SQRT10; // (x+1,y-3) (x+1,y+3)
+ if (v < minv) minv = v;
+
+ if (minv < DT_SQRT13)
+ goto min_attrib;
+
+ v = image_data[r2 - 3] + DT_SQRT13; // (x-3,y-2) (x-3,y+2)
+ if (v < minv) minv = v;
+
+ v = image_data[r2 + 3] + DT_SQRT13; // (x+3,y-2) (x+3,y+2)
+ if (v < minv) minv = v;
+
+ v = image_data[r3 + 2] + DT_SQRT13; // (x+2,y-3) (x+2,y+3)
+ if (v < minv) minv = v;
+
+ v = image_data[r3 - 2] + DT_SQRT13; // (x-2,y-3) (x-2,y+3)
+ if (v < minv) minv = v;
+
+ if (minv < DT_SQRT17)
+ goto min_attrib;
+
+ v = image_data[r1 + 4] + DT_SQRT17; // (x+4,y-1) (x+4,y+1)
+ if (v < minv) minv = v;
+
+ v = image_data[r1 - 4] + DT_SQRT17; // (x-4,y-1) (x-4,y+1)
+ if (v < minv) minv = v;
+
+ v = image_data[r4 - 1] + DT_SQRT17; // (x-1,y-4) (x-1,y+4)
+ if (v < minv) minv = v;
+
+ v = image_data[r4 + 1] + DT_SQRT17; // (x+1,y-4) (x+1,y+4)
+ if (v < minv) minv = v;
+
+ if (minv < DT_SQRT25)
+ goto min_attrib;
+
+ v = image_data[r3 - 4] + DT_SQRT25; // (x-4,y-3) (x-4,y+3)
+ if (v < minv) minv = v;
+
+ v = image_data[r3 + 4] + DT_SQRT25; // (x+4,y-3) (x+4,y+3)
+ if (v < minv) minv = v;
+
+ v = image_data[r4 + 3] + DT_SQRT25; // (x+3,y-4) (x+3,y+4)
+ if (v < minv) minv = v;
+
+ v = image_data[r4 - 3] + DT_SQRT25; // (x-3,y-4) (x-3,y+4)
+ if (v < minv) minv = v;
+
+min_attrib:
+ image_data[r] = minv;
+}
+
+static inline void setValueForwardEdge(int r, int r1, int r2, int width, int x, int y, float *image_data)
+{
+ float v;
+ float minv = image_data[r]; // (x,y)
+
+ if (y > 0)
+ {
+ v = image_data[r1] + DT_ONE; // (x,y-1)
+ if (v < minv) minv = v;
+ }
+
+ if (x > 0)
+ {
+ v = image_data[r - 1] + DT_ONE; // (x-1,y)
+ if (v < minv) minv = v;
+ }
+
+ if (x > 0 && y > 0)
+ {
+ v = image_data[r1 - 1] + DT_SQRT2; // (x-1,y-1)
+ if (v < minv) minv = v;
+ }
+
+ if (x < width-2 && y > 0)
+ {
+ v = image_data[r1 + 1] + DT_SQRT2; // (x+1,y-1)
+ if (v < minv) minv = v;
+ }
+
+ if (x > 0 && y > 1)
+ {
+ v = image_data[r2 - 1] + DT_SQRT5; // (x-1,y-2)
+ if (v < minv) minv = v;
+ }
+
+ if (x < width-2 && y > 1)
+ {
+ v = image_data[r2 + 1] + DT_SQRT5; // (x+1,y-2)
+ if (v < minv) minv = v;
+ }
+
+ if (x < width-3 && y > 0)
+ {
+ v = image_data[r1 + 2] + DT_SQRT5; // (x+2,y-1)
+ if (v < minv) minv = v;
+ }
+
+ if (x > 1 && y > 0)
+ {
+ v = image_data[r1 - 2] + DT_SQRT5; // (x-2,y-1)
+ if (v < minv) minv = v;
+ }
+
+ image_data[r] = minv;
+}
+
+static inline void setValueBackwardEdge(int r, int r1, int r2, int width, int height, int x, int y, float *image_data)
+{
+ float v;
+ float minv = image_data[r]; // (x,y)
+
+ if (x < width-2)
+ {
+ v = image_data[r + 1] + DT_ONE; // (x+1,y)
+ if (v < minv) minv = v;
+ }
+
+ if (y < height-2)
+ {
+ v = image_data[r1] + DT_ONE; // (x,y+1)
+ if (v < minv) minv = v;
+ }
+
+ if (y < height-2 && x > 0)
+ {
+ v = image_data[r1 - 1] + DT_SQRT2; // (x-1,y+1)
+ if (v < minv) minv = v;
+ }
+
+ if (y < height-2 && x < width-2)
+ {
+ v = image_data[r1 + 1] + DT_SQRT2; // (x+1,y+1)
+ if (v < minv) minv = v;
+ }
+
+ if (y < height-2 && x < width-3)
+ {
+ v = image_data[r1 + 2] + DT_SQRT5; // (x+2,y+1)
+ if (v < minv) minv = v;
+ }
+
+ if (y < height-3 && x < width-2)
+ {
+ v = image_data[r2 + 1] + DT_SQRT5; // (x+1,y+2)
+ if (v < minv) minv = v;
+ }
+
+ if (y < height-3 && x > 0)
+ {
+ v = image_data[r2 - 1] + DT_SQRT5; // (x-1,y+2)
+ if (v < minv) minv = v;
+ }
+
+ if (y < height-2 && x > 1)
+ {
+ v = image_data[r1 - 2] + DT_SQRT5; // (x-2,y+1)
+ if (v < minv) minv = v;
+ }
+
+ image_data[r] = minv;
+}
+
+void imProcessDistanceTransform(const imImage* src_image, imImage* dst_image)
+{
+ int i, x, y,
+ offset, offset1, offset2, offset3, offset4,
+ width = src_image->width,
+ height = src_image->height;
+
+ imbyte* src_data = (imbyte*)src_image->data[0];
+ float* dst_data = (float*)dst_image->data[0];
+
+ float max_dist = (float)sqrt(double(width*width + height*height));
+
+ for (i = 0; i < src_image->count; i++)
+ {
+ // if pixel is background, then distance is zero.
+ if (src_data[i])
+ dst_data[i] = max_dist;
+ }
+
+ /* down->top, left->right */
+ for (y = 0; y < height; y++)
+ {
+ offset = y * width;
+ offset1 = offset - width;
+ offset2 = offset - 2*width;
+ offset3 = offset - 3*width;
+ offset4 = offset - 4*width;
+
+ for (x = 0; x < width; x++)
+ {
+ if (src_data[offset])
+ {
+ if (x < 4 || x > width-5 || y < 4 || y > height-5)
+ setValueForwardEdge(offset, offset1, offset2, width, x, y, dst_data);
+ else
+ setValue(offset, offset1, offset2, offset3, offset4, dst_data, 1);
+ }
+
+ offset++;
+ offset1++;
+ offset2++;
+ offset3++;
+ offset4++;
+ }
+ }
+
+ /* top->down, right->left */
+ for (y = height-1; y >= 0; y--)
+ {
+ offset = y * width + width-1;
+ offset1 = offset + width;
+ offset2 = offset + 2*width;
+ offset3 = offset + 3*width;
+ offset4 = offset + 4*width;
+
+ for (x = width-1; x >= 0; x--)
+ {
+ if (src_data[offset])
+ {
+ if (x < 4 || x > width-5 || y < 4 || y > height-5)
+ setValueBackwardEdge(offset, offset1, offset2, width, height, x, y, dst_data);
+ else
+ setValue(offset, offset1, offset2, offset3, offset4, dst_data, 0);
+ }
+
+ offset--;
+ offset1--;
+ offset2--;
+ offset3--;
+ offset4--;
+ }
+ }
+}
+
+static void iFillValue(imbyte* img_data, int x, int y, int width, int value)
+{
+ int r = y * width + x;
+ int r1a = r - width;
+ int r1b = r + width;
+ int v;
+
+ int old_value = img_data[r];
+ img_data[r] = (imbyte)value;
+
+ v = img_data[r1a]; // (x,y-1)
+ if (v == old_value)
+ iFillValue(img_data, x, y-1, width, value);
+
+ v = img_data[r - 1]; // (x-1,y)
+ if (v == old_value)
+ iFillValue(img_data, x-1, y, width, value);
+
+ v = img_data[r1a - 1]; // (x-1,y-1)
+ if (v == old_value)
+ iFillValue(img_data, x-1, y-1, width, value);
+
+ v = img_data[r1a + 1]; // (x+1,y-1)
+ if (v == old_value)
+ iFillValue(img_data, x+1, y-1, width, value);
+
+ v = img_data[r + 1]; // (x+1,y)
+ if (v == old_value)
+ iFillValue(img_data, x+1, y, width, value);
+
+ v = img_data[r1b]; // (x,y+1)
+ if (v == old_value)
+ iFillValue(img_data, x, y+1, width, value);
+
+ v = img_data[r1b - 1]; // (x-1,y+1)
+ if (v == old_value)
+ iFillValue(img_data, x-1, y+1, width, value);
+
+ v = img_data[r1b + 1]; // (x+1,y+1)
+ if (v == old_value)
+ iFillValue(img_data, x+1, y+1, width, value);
+}
+
+static inline int iCheckFalseMaximum(int r, int r2a, int r2b, int width, float *src_data)
+{
+ /* we are ignoring valeys of 1 pixel. */
+ /* this is not 100% fail proof */
+ float v;
+ float maxv = src_data[r]; // (x,y)
+ int r1a = r - width;
+ int r1b = r + width;
+
+ v = src_data[r2a - 1]; // (x-1,y-2)
+ if (v > maxv) return 1;
+
+ v = src_data[r2a]; // (x,y-2)
+ if (v > maxv) return 1;
+
+ v = src_data[r2a + 1]; // (x+1,y-2)
+ if (v > maxv) return 1;
+
+ v = src_data[r2b - 1]; // (x-1,y+2)
+ if (v > maxv) return 1;
+
+ v = src_data[r2b]; // (x,y+2)
+ if (v > maxv) return 1;
+
+ v = src_data[r2b + 1]; // (x+1,y+2)
+ if (v > maxv) return 1;
+
+
+ v = src_data[r2b - 2]; // (x-2,y+2)
+ if (v > maxv) return 1;
+
+ v = src_data[r1b - 2]; // (x-2,y+1)
+ if (v > maxv) return 1;
+
+ v = src_data[r - 2]; // (x-2,y)
+ if (v > maxv) return 1;
+
+ v = src_data[r1a - 2]; // (x-2,y-1)
+ if (v > maxv) return 1;
+
+ v = src_data[r2a - 2]; // (x-2,y-2)
+ if (v > maxv) return 1;
+
+
+ v = src_data[r2a + 2]; // (x+2,y-2)
+ if (v > maxv) return 1;
+
+ v = src_data[r1a + 2]; // (x+2,y-1)
+ if (v > maxv) return 1;
+
+ v = src_data[r + 2]; // (x+2,y)
+ if (v > maxv) return 1;
+
+ v = src_data[r1b + 2]; // (x+2,y+1)
+ if (v > maxv) return 1;
+
+ v = src_data[r2b + 2]; // (x+2,y+2)
+ if (v > maxv) return 1;
+
+ return 0;
+}
+
+static inline void iCheckMaximum(int r, int r1a, int r1b, float *src_data, imbyte* dst_data)
+{
+ int unique = 1;
+ float v;
+ float maxv = src_data[r]; // (x,y)
+
+ v = src_data[r1a]; // (x,y-1)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ v = src_data[r - 1]; // (x-1,y)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ v = src_data[r1a - 1]; // (x-1,y-1)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ v = src_data[r1a + 1]; // (x+1,y-1)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ v = src_data[r + 1]; // (x+1,y)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ v = src_data[r1b]; // (x,y+1)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ v = src_data[r1b - 1]; // (x-1,y+1)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ v = src_data[r1b + 1]; // (x+1,y+1)
+ if (v >= maxv) { maxv = v; unique = 0; }
+
+ if (src_data[r] < maxv) // not a maximum
+ dst_data[r] = 0;
+ else
+ {
+ if (unique) // unique maximum
+ dst_data[r] = 1;
+ else // can be maximum
+ dst_data[r] = 2;
+ }
+}
+
+void imProcessRegionalMaximum(const imImage* src_image, imImage* dst_image)
+{
+ int i, x, y, offset, offsetA, offsetB,
+ width = src_image->width,
+ height = src_image->height;
+
+ float* src_data = (float*)src_image->data[0];
+ imbyte* dst_data = (imbyte*)dst_image->data[0];
+
+ for (y = 1; y < height-1; y++)
+ {
+ offset = y * width + 1;
+ offsetA = offset - width;
+ offsetB = offset + width;
+
+ for (x = 1; x < width-1; x++)
+ {
+ if (src_data[offset])
+ iCheckMaximum(offset, offsetA, offsetB, src_data, dst_data);
+
+ offset++;
+ offsetA++;
+ offsetB++;
+ }
+ }
+
+ // remove false maximum
+ for (y = 2; y < height-2; y++)
+ {
+ offset = y * width + 2;
+ offsetA = offset - 2*width;
+ offsetB = offset + 2*width;
+
+ for (x = 2; x < width-2; x++)
+ {
+ if (dst_data[offset] == 2)
+ {
+ if (iCheckFalseMaximum(offset, offsetA, offsetB, width, src_data))
+ iFillValue(dst_data, x, y, width, 0);
+ }
+
+ offset++;
+ offsetA++;
+ offsetB++;
+ }
+ }
+
+ // update destiny with remaining maximum
+ for (i = 0; i < src_image->count; i++)
+ {
+ if (dst_data[i] == 2)
+ dst_data[i] = 1;
+ }
+}
diff --git a/im/src/process/im_effects.cpp b/im/src/process/im_effects.cpp
new file mode 100755
index 0000000..7f65ce6
--- /dev/null
+++ b/im/src/process/im_effects.cpp
@@ -0,0 +1,86 @@
+/** \file
+ * \brief Effects
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_effects.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math.h>
+#include <im_complex.h>
+
+#include "im_process_pon.h"
+#include "im_math_op.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+static unsigned char BoxMean(imbyte *map, int offset, int shift, int hbox_size, int vbox_size)
+{
+ map += offset;
+ int acum = 0;
+ for (int i = 0; i < vbox_size; i++)
+ {
+ for (int j = 0; j < hbox_size; j++)
+ {
+ acum += *map++;
+ }
+
+ map += shift;
+ }
+
+ return (unsigned char)(acum / (vbox_size*hbox_size));
+}
+
+static void BoxSet(imbyte *map, int offset, int shift, int hbox_size, int vbox_size, unsigned char value)
+{
+ map += offset;
+ for (int i = 0; i < vbox_size; i++)
+ {
+ for (int j = 0; j < hbox_size; j++)
+ {
+ *map++ = value;
+ }
+
+ map += shift;
+ }
+}
+
+void imProcessPixelate(const imImage* src_image, imImage* dst_image, int box_size)
+{
+ int hbox = ((src_image->width + box_size-1)/ box_size);
+ int vbox = ((src_image->height + box_size-1)/ box_size);
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ imbyte *src_map=(imbyte*)src_image->data[i];
+ imbyte *dst_map=(imbyte*)dst_image->data[i];
+ int vbox_size = box_size;
+
+ for (int bv = 0; bv < vbox; bv++)
+ {
+ int bv_pos = bv*box_size;
+ if (bv == vbox-1) vbox_size = src_image->height - bv_pos;
+ int hbox_size = box_size;
+
+ for (int bh = 0; bh < hbox; bh++)
+ {
+ int bh_pos = bh*box_size;
+ if (bh == hbox-1) hbox_size = src_image->width - bh_pos;
+ int offset = bv_pos*src_image->width + bh_pos;
+ int shift = src_image->width - hbox_size;
+ unsigned char mean = BoxMean(src_map, offset, shift, hbox_size, vbox_size);
+ BoxSet(dst_map, offset, shift, hbox_size, vbox_size, mean);
+ }
+ }
+ }
+}
+
+void imProcessPosterize(const imImage* src_image, imImage* dst_image, int level)
+{
+ unsigned char mask = (unsigned char)(0xFF << level);
+ imProcessBitMask(src_image, dst_image, mask, IM_BIT_AND);
+}
+
diff --git a/im/src/process/im_fft.cpp b/im/src/process/im_fft.cpp
new file mode 100755
index 0000000..2a36880
--- /dev/null
+++ b/im/src/process/im_fft.cpp
@@ -0,0 +1,198 @@
+/** \file
+ * \brief Fast Fourier Transform using FFTW library
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_fft.cpp,v 1.2 2009/08/20 12:37:11 scuri Exp $
+ */
+
+#include <im.h>
+#include <im_util.h>
+#include <im_complex.h>
+#include <im_convert.h>
+
+#include "im_process.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <memory.h>
+
+#ifdef USE_FFTW3
+#include "fftw3.h"
+#else
+#include "fftw.h"
+#endif
+
+static void iCopyCol(imcfloat *map1, imcfloat *map2, int height, int width1, int width2)
+{
+ int i;
+ for(i = 0; i < height; i++)
+ {
+ *map1 = *map2;
+ map1 += width1;
+ map2 += width2;
+ }
+}
+
+static void iCenterFFT(imcfloat *map, int width, int height, int inverse)
+{
+ imcfloat *map1, *map2, *map3, *tmp;
+ int i, half1_width, half2_width, half1_height, half2_height;
+
+ if (inverse)
+ {
+ half1_width = width/2;
+ half1_height = height/2;
+
+ half2_width = (width+1)/2;
+ half2_height = (height+1)/2;
+ }
+ else
+ {
+ half1_width = (width+1)/2;
+ half1_height = (height+1)/2;
+
+ half2_width = width/2;
+ half2_height = height/2;
+ }
+
+ tmp = (imcfloat*)malloc(half1_width*sizeof(imcfloat));
+
+ map1 = map;
+ map2 = map + half1_width;
+ map3 = map + half2_width;
+ for(i = 0; i < height; i++)
+ {
+ memcpy(tmp, map1, half1_width*sizeof(imcfloat));
+ memcpy(map1, map2, half2_width*sizeof(imcfloat));
+ memcpy(map3, tmp, half1_width*sizeof(imcfloat));
+
+ map1 += width;
+ map2 += width;
+ map3 += width;
+ }
+
+ free(tmp);
+
+ tmp = (imcfloat*)malloc(half1_height*sizeof(imcfloat));
+
+ map1 = map;
+ map2 = map + half1_height*width;
+ map3 = map + half2_height*width;
+ for(i = 0; i < width; i++)
+ {
+ iCopyCol(tmp, map1, half1_height, 1, width);
+ iCopyCol(map1, map2, half2_height, width, width);
+ iCopyCol(map3, tmp, half1_height, width, 1);
+
+ map1++;
+ map2++;
+ map3++;
+ }
+
+ free(tmp);
+}
+
+static void iDoFFT(void *map, int width, int height, int inverse, int center, int normalize)
+{
+ if (inverse && center)
+ iCenterFFT((imcfloat*)map, width, height, inverse);
+
+#ifdef USE_FFTW3
+ fftwf_plan plan = fftwf_plan_dft_2d(height, width,
+ (fftwf_complex*)map, (fftwf_complex*)map, // in-place transform
+ inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
+ fftwf_execute(plan);
+ fftwf_destroy_plan(plan);
+#else
+ fftwnd_plan plan = fftw2d_create_plan(height, width, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE|FFTW_IN_PLACE);
+ fftwnd(plan, 1, (FFTW_COMPLEX*)map, 1, 0, 0, 0, 0);
+ fftwnd_destroy_plan(plan);
+#endif
+
+ if (!inverse && center)
+ iCenterFFT((imcfloat*)map, width, height, inverse);
+
+ if (normalize)
+ {
+ float NM = (float)(width * height);
+ int count = (int)(2*NM);
+
+ if (normalize == 1)
+ NM = (float)sqrt(NM);
+
+ float *fmap = (float*)map;
+ for (int i = 0; i < count; i++)
+ *fmap++ /= NM;
+ }
+}
+
+void imProcessSwapQuadrants(imImage* image, int inverse)
+{
+ for (int i = 0; i < image->depth; i++)
+ iCenterFFT((imcfloat*)image->data[i], image->width, image->height, inverse);
+}
+
+void imProcessFFTraw(imImage* image, int inverse, int center, int normalize)
+{
+ for (int i = 0; i < image->depth; i++)
+ iDoFFT(image->data[i], image->width, image->height, inverse, center, normalize);
+}
+
+void imProcessFFT(const imImage* src_image, imImage* dst_image)
+{
+ if (src_image->data_type != IM_CFLOAT)
+ imConvertDataType(src_image, dst_image, 0, 0, 0, 0);
+ else
+ imImageCopy(src_image, dst_image);
+
+ imProcessFFTraw(dst_image, 0, 1, 0); // forward, centered, unnormalized
+}
+
+void imProcessIFFT(const imImage* src_image, imImage* dst_image)
+{
+ imImageCopy(src_image, dst_image);
+
+ imProcessFFTraw(dst_image, 1, 1, 2); // inverse, uncentered, double normalized
+}
+
+void imProcessCrossCorrelation(const imImage* src_image1, const imImage* src_image2, imImage* dst_image)
+{
+ imImage *tmp_image = imImageCreate(src_image2->width, src_image2->height, src_image2->color_space, IM_CFLOAT);
+ if (!tmp_image)
+ return;
+
+ if (src_image2->data_type != IM_CFLOAT)
+ imConvertDataType(src_image2, tmp_image, 0, 0, 0, 0);
+ else
+ imImageCopy(src_image2, tmp_image);
+
+ if (src_image1->data_type != IM_CFLOAT)
+ imConvertDataType(src_image1, dst_image, 0, 0, 0, 0);
+ else
+ imImageCopy(src_image1, dst_image);
+
+ imProcessFFTraw(tmp_image, 0, 1, 1); // forward, centered, normalized
+ imProcessFFTraw(dst_image, 0, 1, 1);
+
+ imProcessMultiplyConj(dst_image, tmp_image, dst_image);
+
+ imProcessFFTraw(dst_image, 1, 1, 1); // inverse, uncentered, normalized
+ imProcessSwapQuadrants(dst_image, 0); // from origin to center
+
+ imImageDestroy(tmp_image);
+}
+
+void imProcessAutoCorrelation(const imImage* src_image, imImage* dst_image)
+{
+ if (src_image->data_type != IM_CFLOAT)
+ imConvertDataType(src_image, dst_image, 0, 0, 0, 0);
+ else
+ imImageCopy(src_image, dst_image);
+
+ imProcessFFTraw(dst_image, 0, 0, 1); // forward, at origin, normalized
+
+ imProcessMultiplyConj(dst_image, dst_image, dst_image);
+
+ imProcessFFTraw(dst_image, 1, 0, 1); // inverse, at origin, normalized
+ imProcessSwapQuadrants(dst_image, 0); // from origin to center
+}
diff --git a/im/src/process/im_geometric.cpp b/im/src/process/im_geometric.cpp
new file mode 100755
index 0000000..a0b5129
--- /dev/null
+++ b/im/src/process/im_geometric.cpp
@@ -0,0 +1,724 @@
+/** \file
+ * \brief Geometric Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_geometric.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_counter.h>
+
+#include "im_process_loc.h"
+#include "im_math_op.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+static inline void imRect2Polar(float x, float y, float *radius, float *theta)
+{
+ *radius = sqrtf(x*x + y*y);
+ *theta = atan2f(y, x);
+}
+
+static inline void imPolar2Rect(float radius, float theta, float *x, float *y)
+{
+ *x = radius * cosf(theta);
+ *y = radius * sinf(theta);
+}
+
+static inline void swirl_invtransf(int x, int y, float *xl, float *yl, float k, float xc, float yc)
+{
+ float radius, theta;
+ x -= (int)xc;
+ y -= (int)yc;
+
+ imRect2Polar((float)x, (float)y, &radius, &theta);
+
+ theta += k * radius;
+
+ imPolar2Rect(radius, theta, xl, yl);
+
+ *xl += xc;
+ *yl += yc;
+}
+
+template <class DT, class DTU>
+static int Swirl(int width, int height, DT *src_map, DT *dst_map,
+ float k, int counter, DTU Dummy, int order)
+{
+ float xl, yl;
+ float xc = float(width/2.);
+ float yc = float(height/2.);
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ swirl_invtransf(x, y, &xl, &yl, k, xc, yc);
+
+ // if inside the original image broad area
+ if (xl > 0.0 && yl > 0.0 && xl < width && yl < height)
+ {
+ if (order == 1)
+ *dst_map = imBilinearInterpolation(width, height, src_map, xl, yl);
+ else if (order == 3)
+ *dst_map = imBicubicInterpolation(width, height, src_map, xl, yl, Dummy);
+ else
+ *dst_map = imZeroOrderInterpolation(width, height, src_map, xl, yl);
+ }
+
+ dst_map++;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline void radial_invtransf(int x, int y, float *xl, float *yl, float k1, float xc, float yc)
+{
+ float aux;
+ x -= (int)xc;
+ y -= (int)yc;
+ aux = 1.0f + k1*(x*x + y*y);
+ *xl = x*aux + xc;
+ *yl = y*aux + yc;
+}
+
+template <class DT, class DTU>
+static int Radial(int width, int height, DT *src_map, DT *dst_map,
+ float k1, int counter, DTU Dummy, int order)
+{
+ float xl, yl;
+ float xc = float(width/2.);
+ float yc = float(height/2.);
+ int diag = (int)sqrt(float(width*width + height*height));
+
+ k1 /= (diag * diag);
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ radial_invtransf(x, y, &xl, &yl, k1, xc, yc);
+
+ // if inside the original image broad area
+ if (xl > 0.0 && yl > 0.0 && xl < width && yl < height)
+ {
+ if (order == 1)
+ *dst_map = imBilinearInterpolation(width, height, src_map, xl, yl);
+ else if (order == 3)
+ *dst_map = imBicubicInterpolation(width, height, src_map, xl, yl, Dummy);
+ else
+ *dst_map = imZeroOrderInterpolation(width, height, src_map, xl, yl);
+ }
+
+ dst_map++;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+//*******************************************************************************************
+//rotate_invtransf
+// shift the center to the origin of the destiny image
+// rotates centrered in the origin
+// shift the origin back to the center of the original image
+//*******************************************************************************************
+
+inline void rotate_invtransf(int x, int y, float *xl, float *yl, double cos0, double sin0, float dcx, float dcy, float scx, float scy)
+{
+ double xr = x+0.5 - dcx;
+ double yr = y+0.5 - dcy;
+ *xl = float(xr * cos0 - yr * sin0 + scx);
+ *yl = float(xr * sin0 + yr * cos0 + scy);
+}
+
+template <class DT, class DTU>
+static int RotateCenter(int src_width, int src_height, DT *src_map,
+ int dst_width, int dst_height, DT *dst_map,
+ double cos0, double sin0, int counter, DTU Dummy, int order)
+{
+ float xl, yl;
+ float dcx = float(dst_width/2.);
+ float dcy = float(dst_height/2.);
+ float scx = float(src_width/2.);
+ float scy = float(src_height/2.);
+
+ for (int y = 0; y < dst_height; y++)
+ {
+ for (int x = 0; x < dst_width; x++)
+ {
+ rotate_invtransf(x, y, &xl, &yl, cos0, sin0, dcx, dcy, scx, scy);
+
+ // if inside the original image broad area
+ if (xl > 0.0 && yl > 0.0 && xl < src_width && yl < src_height)
+ {
+ if (order == 1)
+ *dst_map = imBilinearInterpolation(src_width, src_height, src_map, xl, yl);
+ else if (order == 3)
+ *dst_map = imBicubicInterpolation(src_width, src_height, src_map, xl, yl, Dummy);
+ else
+ *dst_map = imZeroOrderInterpolation(src_width, src_height, src_map, xl, yl);
+ }
+
+ dst_map++;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+template <class DT, class DTU>
+static int Rotate(int src_width, int src_height, DT *src_map,
+ int dst_width, int dst_height, DT *dst_map,
+ double cos0, double sin0, int ref_x, int ref_y, int to_origin,
+ int counter, DTU Dummy, int order)
+{
+ float xl, yl;
+ float sx = float(ref_x);
+ float sy = float(ref_y);
+ float dx = sx;
+ float dy = sy;
+ if (to_origin)
+ {
+ dx = 0;
+ dy = 0;
+ }
+
+ for (int y = 0; y < dst_height; y++)
+ {
+ for (int x = 0; x < dst_width; x++)
+ {
+ rotate_invtransf(x, y, &xl, &yl, cos0, sin0, dx, dy, sx, sy);
+
+ // if inside the original image broad area
+ if (xl > 0.0 && yl > 0.0 && xl < src_width && yl < src_height)
+ {
+ if (order == 1)
+ *dst_map = imBilinearInterpolation(src_width, src_height, src_map, xl, yl);
+ else if (order == 3)
+ *dst_map = imBicubicInterpolation(src_width, src_height, src_map, xl, yl, Dummy);
+ else
+ *dst_map = imZeroOrderInterpolation(src_width, src_height, src_map, xl, yl);
+ }
+
+ dst_map++;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+template <class DT>
+static void Rotate90(int src_width,
+ int src_height,
+ DT *src_map,
+ int dst_width,
+ int dst_height,
+ DT *dst_map,
+ int dir)
+{
+ int xd,yd,x,y;
+
+ if (dir == 1)
+ xd = 0;
+ else
+ xd = dst_width - 1;
+
+ for(y = 0 ; y < src_height ; y++)
+ {
+ if (dir == 1)
+ yd = dst_height - 1;
+ else
+ yd = 0;
+
+ for(x = 0 ; x < src_width ; x++)
+ {
+ dst_map[yd * dst_width + xd] = src_map[y * src_width + x];
+
+ if (dir == 1)
+ yd--;
+ else
+ yd++;
+ }
+
+ if (dir == 1)
+ xd++;
+ else
+ xd--;
+ }
+}
+
+template <class DT>
+static void Rotate180(int src_width,
+ int src_height,
+ DT *src_map,
+ int dst_width,
+ int dst_height,
+ DT *dst_map)
+{
+ int xd,yd,x,y;
+
+ yd = dst_height - 1;
+
+ for(y = 0 ; y < src_height ; y++)
+ {
+ xd = dst_width - 1;
+
+ for(x = 0 ; x < src_width ; x++)
+ {
+ dst_map[yd * dst_width + xd] = src_map[y * src_width + x];
+ xd--;
+ }
+
+ yd--;
+ }
+}
+
+template <class DT>
+static void Mirror(int src_width,
+ int src_height,
+ DT *src_map,
+ int dst_width,
+ int dst_height,
+ DT *dst_map)
+{
+ int xd,x,y;
+ (void)dst_height;
+
+ if (src_map == dst_map) // check of in-place operation
+ {
+ int half_width = src_width/2;
+ for(y = 0 ; y < src_height; y++)
+ {
+ xd = dst_width - 1;
+
+ for(x = 0 ; x < half_width; x++)
+ {
+ DT temp_value = src_map[y * dst_width + xd];
+ src_map[y * dst_width + xd] = src_map[y * src_width + x];
+ src_map[y * src_width + x] = temp_value;
+ xd--;
+ }
+ }
+ }
+ else
+ {
+ for(y = 0 ; y < src_height; y++)
+ {
+ xd = dst_width - 1;
+
+ for(x = 0 ; x < src_width; x++)
+ {
+ dst_map[y * dst_width + xd] = src_map[y * src_width + x];
+ xd--;
+ }
+ }
+ }
+}
+
+template <class DT>
+static void Flip(int src_width,
+ int src_height,
+ DT *src_map,
+ int dst_width,
+ int dst_height,
+ DT *dst_map)
+{
+ int yd,y;
+
+ yd = dst_height - 1;
+
+ if (src_map == dst_map) // check of in-place operation
+ {
+ DT* temp_line = (DT*)malloc(src_width*sizeof(DT));
+ int half_height = src_height/2;
+
+ for(y = 0 ; y < half_height; y++)
+ {
+ memcpy(temp_line, dst_map+yd*dst_width, src_width * sizeof(DT));
+ memcpy(dst_map+yd*dst_width, src_map+y*src_width, src_width * sizeof(DT));
+ memcpy(src_map+y*src_width, temp_line,src_width * sizeof(DT));
+ yd--;
+ }
+
+ free(temp_line);
+ }
+ else
+ {
+ for(y = 0 ; y < src_height; y++)
+ {
+ memcpy(dst_map+yd*dst_width,src_map+y*src_width,src_width * sizeof(DT));
+ yd--;
+ }
+ }
+}
+
+template <class DT>
+static void InterlaceSplit(int src_width,
+ int src_height,
+ DT *src_map,
+ int dst_width,
+ DT *dst_map1,
+ DT *dst_map2)
+{
+ int yd = 0, y;
+
+ for(y = 0; y < src_height; y++)
+ {
+ if (y%2)
+ {
+ memcpy(dst_map2+yd*dst_width, src_map+y*src_width, src_width * sizeof(DT));
+ yd++; // increment only when odd
+ }
+ else
+ memcpy(dst_map1+yd*dst_width, src_map+y*src_width, src_width * sizeof(DT));
+ }
+}
+
+void imProcessRotate90(const imImage* src_image, imImage* dst_image, int dir)
+{
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ Rotate90(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image->width, dst_image->height, (imbyte*)dst_image->data[i], dir);
+ break;
+ case IM_USHORT:
+ Rotate90(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image->width, dst_image->height, (imushort*)dst_image->data[i], dir);
+ break;
+ case IM_INT:
+ Rotate90(src_image->width, src_image->height, (int*)src_image->data[i], dst_image->width, dst_image->height, (int*)dst_image->data[i], dir);
+ break;
+ case IM_FLOAT:
+ Rotate90(src_image->width, src_image->height, (float*)src_image->data[i], dst_image->width, dst_image->height, (float*)dst_image->data[i], dir);
+ break;
+ case IM_CFLOAT:
+ Rotate90(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i], dir);
+ break;
+ }
+ }
+}
+
+void imProcessRotate180(const imImage* src_image, imImage* dst_image)
+{
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ Rotate180(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image->width, dst_image->height, (imbyte*)dst_image->data[i]);
+ break;
+ case IM_USHORT:
+ Rotate180(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image->width, dst_image->height, (imushort*)dst_image->data[i]);
+ break;
+ case IM_INT:
+ Rotate180(src_image->width, src_image->height, (int*)src_image->data[i], dst_image->width, dst_image->height, (int*)dst_image->data[i]);
+ break;
+ case IM_FLOAT:
+ Rotate180(src_image->width, src_image->height, (float*)src_image->data[i], dst_image->width, dst_image->height, (float*)dst_image->data[i]);
+ break;
+ case IM_CFLOAT:
+ Rotate180(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i]);
+ break;
+ }
+ }
+}
+
+int imProcessRadial(const imImage* src_image, imImage* dst_image, float k1, int order)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin("Radial Distort");
+ imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing...");
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = Radial(src_image->width, src_image->height, (imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], k1, counter, float(0), order);
+ break;
+ case IM_USHORT:
+ ret = Radial(src_image->width, src_image->height, (imushort*)src_image->data[i], (imushort*)dst_image->data[i], k1, counter, float(0), order);
+ break;
+ case IM_INT:
+ ret = Radial(src_image->width, src_image->height, (int*)src_image->data[i], (int*)dst_image->data[i], k1, counter, float(0), order);
+ break;
+ case IM_FLOAT:
+ ret = Radial(src_image->width, src_image->height, (float*)src_image->data[i], (float*)dst_image->data[i], k1, counter, float(0), order);
+ break;
+ case IM_CFLOAT:
+ ret = Radial(src_image->width, src_image->height, (imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], k1, counter, imcfloat(0,0), order);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+int imProcessSwirl(const imImage* src_image, imImage* dst_image, float k, int order)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin("Swirl Distort");
+ imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing...");
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = Swirl(src_image->width, src_image->height, (imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], k, counter, float(0), order);
+ break;
+ case IM_USHORT:
+ ret = Swirl(src_image->width, src_image->height, (imushort*)src_image->data[i], (imushort*)dst_image->data[i], k, counter, float(0), order);
+ break;
+ case IM_INT:
+ ret = Swirl(src_image->width, src_image->height, (int*)src_image->data[i], (int*)dst_image->data[i], k, counter, float(0), order);
+ break;
+ case IM_FLOAT:
+ ret = Swirl(src_image->width, src_image->height, (float*)src_image->data[i], (float*)dst_image->data[i], k, counter, float(0), order);
+ break;
+ case IM_CFLOAT:
+ ret = Swirl(src_image->width, src_image->height, (imcfloat*)src_image->data[i], (imcfloat*)dst_image->data[i], k, counter, imcfloat(0,0), order);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+//*******************************************************************************************
+//rotate_transf
+// In this case shift to the origin, rotate, but do NOT shift back
+//*******************************************************************************************
+
+static void rotate_transf(float cx, float cy, int x, int y, float *xl, float *yl, double cos0, double sin0)
+{
+ double xr = x+0.5 - cx;
+ double yr = y+0.5 - cy;
+ *xl = float( xr*cos0 + yr*sin0);
+ *yl = float(-xr*sin0 + yr*cos0);
+}
+
+void imProcessCalcRotateSize(int width, int height, int *new_width, int *new_height, double cos0, double sin0)
+{
+ float xl, yl, xmin, xmax, ymin, ymax;
+ float wd2 = float(width)/2;
+ float hd2 = float(height)/2;
+
+ rotate_transf(wd2, hd2, 0, 0, &xl, &yl, cos0, sin0);
+ xmin = xl; ymin = yl;
+ xmax = xl; ymax = yl;
+
+ rotate_transf(wd2, hd2, width-1, height-1, &xl, &yl, cos0, sin0);
+ xmin = min_op(xmin, xl); ymin = min_op(ymin, yl);
+ xmax = max_op(xmax, xl); ymax = max_op(ymax, yl);
+
+ rotate_transf(wd2, hd2, 0, height-1, &xl, &yl, cos0, sin0);
+ xmin = min_op(xmin, xl); ymin = min_op(ymin, yl);
+ xmax = max_op(xmax, xl); ymax = max_op(ymax, yl);
+
+ rotate_transf(wd2, hd2, width-1, 0, &xl, &yl, cos0, sin0);
+ xmin = min_op(xmin, xl); ymin = min_op(ymin, yl);
+ xmax = max_op(xmax, xl); ymax = max_op(ymax, yl);
+
+ *new_width = (int)(xmax - xmin + 2.0);
+ *new_height = (int)(ymax - ymin + 2.0);
+}
+
+int imProcessRotate(const imImage* src_image, imImage* dst_image, double cos0, double sin0, int order)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin("Rotate");
+ imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing...");
+
+ if (src_image->color_space == IM_MAP)
+ {
+ ret = RotateCenter(src_image->width, src_image->height, (imbyte*)src_image->data[0], dst_image->width, dst_image->height, (imbyte*)dst_image->data[0], cos0, sin0, counter, float(0), 0);
+ }
+ else
+ {
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = RotateCenter(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image->width, dst_image->height, (imbyte*)dst_image->data[i], cos0, sin0, counter, float(0), order);
+ break;
+ case IM_USHORT:
+ ret = RotateCenter(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image->width, dst_image->height, (imushort*)dst_image->data[i], cos0, sin0, counter, float(0), order);
+ break;
+ case IM_INT:
+ ret = RotateCenter(src_image->width, src_image->height, (int*)src_image->data[i], dst_image->width, dst_image->height, (int*)dst_image->data[i], cos0, sin0, counter, float(0), order);
+ break;
+ case IM_FLOAT:
+ ret = RotateCenter(src_image->width, src_image->height, (float*)src_image->data[i], dst_image->width, dst_image->height, (float*)dst_image->data[i], cos0, sin0, counter, float(0), order);
+ break;
+ case IM_CFLOAT:
+ ret = RotateCenter(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i], cos0, sin0, counter, imcfloat(0,0), order);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+int imProcessRotateRef(const imImage* src_image, imImage* dst_image, double cos0, double sin0, int x, int y, int to_origin, int order)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin("RotateRef");
+ imCounterTotal(counter, dst_image->depth*dst_image->height, "Processing...");
+
+ if (src_image->color_space == IM_MAP)
+ {
+ ret = Rotate(src_image->width, src_image->height, (imbyte*)src_image->data[0], dst_image->width, dst_image->height, (imbyte*)dst_image->data[0], cos0, sin0, x, y, to_origin, counter, float(0), 0);
+ }
+ else
+ {
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = Rotate(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image->width, dst_image->height, (imbyte*)dst_image->data[i], cos0, sin0, x, y, to_origin, counter, float(0), order);
+ break;
+ case IM_USHORT:
+ ret = Rotate(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image->width, dst_image->height, (imushort*)dst_image->data[i], cos0, sin0, x, y, to_origin, counter, float(0), order);
+ break;
+ case IM_INT:
+ ret = Rotate(src_image->width, src_image->height, (int*)src_image->data[i], dst_image->width, dst_image->height, (int*)dst_image->data[i], cos0, sin0, x, y, to_origin, counter, float(0), order);
+ break;
+ case IM_FLOAT:
+ ret = Rotate(src_image->width, src_image->height, (float*)src_image->data[i], dst_image->width, dst_image->height, (float*)dst_image->data[i], cos0, sin0, x, y, to_origin, counter, float(0), order);
+ break;
+ case IM_CFLOAT:
+ ret = Rotate(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i], cos0, sin0, x, y, to_origin, counter, imcfloat(0,0), order);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+void imProcessMirror(const imImage* src_image, imImage* dst_image)
+{
+ int i;
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ Mirror(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image->width, dst_image->height, (imbyte*)dst_image->data[i]);
+ break;
+ case IM_USHORT:
+ Mirror(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image->width, dst_image->height, (imushort*)dst_image->data[i]);
+ break;
+ case IM_INT:
+ Mirror(src_image->width, src_image->height, (int*)src_image->data[i], dst_image->width, dst_image->height, (int*)dst_image->data[i]);
+ break;
+ case IM_FLOAT:
+ Mirror(src_image->width, src_image->height, (float*)src_image->data[i], dst_image->width, dst_image->height, (float*)dst_image->data[i]);
+ break;
+ case IM_CFLOAT:
+ Mirror(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i]);
+ break;
+ }
+ }
+}
+
+void imProcessFlip(const imImage* src_image, imImage* dst_image)
+{
+ int i;
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ Flip(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image->width, dst_image->height, (imbyte*)dst_image->data[i]);
+ break;
+ case IM_USHORT:
+ Flip(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image->width, dst_image->height, (imushort*)dst_image->data[i]);
+ break;
+ case IM_INT:
+ Flip(src_image->width, src_image->height, (int*)src_image->data[i], dst_image->width, dst_image->height, (int*)dst_image->data[i]);
+ break;
+ case IM_FLOAT:
+ Flip(src_image->width, src_image->height, (float*)src_image->data[i], dst_image->width, dst_image->height, (float*)dst_image->data[i]);
+ break;
+ case IM_CFLOAT:
+ Flip(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i]);
+ break;
+ }
+ }
+}
+
+void imProcessInterlaceSplit(const imImage* src_image, imImage* dst_image1, imImage* dst_image2)
+{
+ int i;
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ InterlaceSplit(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image1->width, (imbyte*)dst_image1->data[i], (imbyte*)dst_image2->data[i]);
+ break;
+ case IM_USHORT:
+ InterlaceSplit(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image1->width, (imushort*)dst_image1->data[i], (imushort*)dst_image2->data[i]);
+ break;
+ case IM_INT:
+ InterlaceSplit(src_image->width, src_image->height, (int*)src_image->data[i], dst_image1->width, (int*)dst_image1->data[i], (int*)dst_image2->data[i]);
+ break;
+ case IM_FLOAT:
+ InterlaceSplit(src_image->width, src_image->height, (float*)src_image->data[i], dst_image1->width, (float*)dst_image1->data[i], (float*)dst_image2->data[i]);
+ break;
+ case IM_CFLOAT:
+ InterlaceSplit(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image1->width, (imcfloat*)dst_image1->data[i], (imcfloat*)dst_image2->data[i]);
+ break;
+ }
+ }
+}
diff --git a/im/src/process/im_histogram.cpp b/im/src/process/im_histogram.cpp
new file mode 100755
index 0000000..e6796fe
--- /dev/null
+++ b/im/src/process/im_histogram.cpp
@@ -0,0 +1,105 @@
+/** \file
+ * \brief Histogram Based Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_histogram.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math.h>
+
+#include "im_process_pon.h"
+#include "im_process_ana.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+static void iExpandHistogram(const imImage* src_image, imImage* dst_image, int low_level, int high_level)
+{
+ int i, value;
+
+ imbyte re_map[256];
+ memset(re_map, 0, 256);
+
+ int range = high_level-low_level+1;
+ float factor = 256.0f / (float)range;
+
+ for (i = 0; i < 256; i++)
+ {
+ if (i < low_level)
+ re_map[i] = 0;
+ else if (i > high_level)
+ re_map[i] = 255;
+ else
+ {
+ value = imResample(i - low_level, factor);
+ re_map[i] = (imbyte)IM_BYTECROP(value);
+ }
+ }
+
+ imbyte* dst_map = (imbyte*)dst_image->data[0];
+ imbyte* src_map = (imbyte*)src_image->data[0];
+ int total_count = src_image->count*src_image->depth;
+ for (i = 0; i < total_count; i++)
+ dst_map[i] = re_map[src_map[i]];
+}
+
+void imProcessExpandHistogram(const imImage* src_image, imImage* dst_image, float percent)
+{
+ unsigned long histo[256];
+ imCalcGrayHistogram(src_image, histo, 0);
+
+ unsigned long acum, cut = (unsigned long)((src_image->count * percent) / 100.0f);
+ int low_level, high_level;
+
+ acum = 0;
+ for (low_level = 0; low_level < 256; low_level++)
+ {
+ acum += histo[low_level];
+ if (acum > cut)
+ break;
+ }
+
+ acum = 0;
+ for (high_level = 255; high_level > 0; high_level--)
+ {
+ acum += histo[high_level];
+ if (acum > cut)
+ break;
+ }
+
+ if (low_level >= high_level)
+ {
+ low_level = 0;
+ high_level = 255;
+ }
+
+ iExpandHistogram(src_image, dst_image, low_level, high_level);
+}
+
+void imProcessEqualizeHistogram(const imImage* src_image, imImage* dst_image)
+{
+ int i, value;
+
+ imbyte re_map[256];
+ memset(re_map, 0, 256);
+
+ unsigned long histo[256];
+ imCalcGrayHistogram(src_image, histo, 1);
+
+ float factor = 256.0f / (float)src_image->count;
+
+ for (i = 0; i < 256; i++)
+ {
+ value = imResample(histo[i], factor);
+ re_map[i] = (imbyte)IM_BYTECROP(value);
+ }
+
+ imbyte* dst_map = (imbyte*)dst_image->data[0];
+ imbyte* src_map = (imbyte*)src_image->data[0];
+ int total_count = src_image->count*src_image->depth;
+ for (i = 0; i < total_count; i++)
+ dst_map[i] = re_map[src_map[i]];
+}
diff --git a/im/src/process/im_houghline.cpp b/im/src/process/im_houghline.cpp
new file mode 100755
index 0000000..6ead982
--- /dev/null
+++ b/im/src/process/im_houghline.cpp
@@ -0,0 +1,435 @@
+/** \file
+ * \brief Hough Transform
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_houghline.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+#include <im.h>
+#include <im_util.h>
+#include <im_complex.h>
+#include <im_convert.h>
+#include <im_counter.h>
+
+#include "im_process_glo.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static double *costab=NULL, *sintab=NULL;
+
+static int hgAbs(int x)
+{
+ return x < 0? -x: x;
+}
+
+typedef struct _point
+{
+ int rho, theta, count;
+} point;
+
+typedef struct _listnode
+{
+ struct _listnode *next;
+ point pt;
+} listnode;
+
+static listnode* listnew(point *pt)
+{
+ listnode* node = (listnode*)malloc(sizeof(listnode));
+ node->next = NULL;
+ node->pt = *pt;
+ return node;
+}
+
+static listnode* listadd(listnode* node, point *pt)
+{
+ node->next = listnew(pt);
+ return node->next;
+}
+
+/* minimum angle to match similar angles */
+#define THETA_DELTA1 0.05 /* radians */
+#define THETA_DELTA2 3 /* degrees */
+
+static int ptNear(point* pt1, point* pt2, int rho_delta)
+{
+ int theta_diff = hgAbs(pt1->theta - pt2->theta);
+ if ((hgAbs(pt1->rho - pt2->rho) < rho_delta && theta_diff < THETA_DELTA2) ||
+ (hgAbs(pt1->rho + pt2->rho) < rho_delta && 180-theta_diff < THETA_DELTA2))
+ {
+ if (pt2->count > pt1->count)
+ return 2; /* replace the line */
+ else
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static listnode* listadd_filtered(listnode* list, listnode* cur_node, point *pt, int rho_delta)
+{
+ int ret;
+ listnode* lt = list;
+ while (lt)
+ {
+ ret = ptNear(&lt->pt, pt, rho_delta);
+ if (ret)
+ {
+ if (ret == 2)
+ lt->pt = *pt; /* replace the line */
+ return cur_node;
+ }
+ lt = lt->next;
+ }
+
+ cur_node->next = listnew(pt);
+ return cur_node->next;
+}
+
+/*C* Initial version from XITE
+
+ houghLine
+ $Id: im_houghline.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ Copyright 1990, Blab, UiO
+ Image processing lab, Department of Informatics
+ University of Oslo
+ E-mail: blab@ifi.uio.no
+________________________________________________________________
+
+ houghLine - Hough transform for line detection
+
+ Description:
+ Performs a Hough transform to detect lines. Every band in the
+ input image 'inimage' is transformed to a two dimensional
+ Hough space, a (theta, rho) space.
+
+ After creating the transform, the Hough space may be searched
+ for local maxima. Within each band, only the largest local
+ maximum (maxima) within a 'ws'x'ws' area is registered.
+ Besides, only maxima with number of updates above a limit
+ given by the ul option are used.
+
+ updateLimit determines the minimum number of updates for a maximum
+ to be used. The minimum number is determined from 'updateLimit'
+ and the size of the hough space image:
+ | updateLimit * MAX(horizontal size, vertical size)
+ Default: 0.1.
+
+ All pixels above zero in the 'input' band are
+ transformed to (theta,rho) space in the 'output'
+ band. The 'input' band may have any size, while
+ the 'output' band currently must be at least
+ | xsize: 180
+ | ysize: 2 * sqrt(inputXsize*inputXsize +
+ | inputYsize*inputYsize) + 1
+
+ Notice that band x coordinates 1..180 correspond
+ to angles theta = 0 .. 179, and y coordinates
+ 1..YSIZE correspond to rho = -(ysize/2) .. ysize/2.
+
+ Restrictions:
+ 'input' must have pixel type imbyte.
+ 'output' must have pixel type int.
+
+ Author: Tor Lønnestad, BLAB, Ifi, UiO
+*/
+
+
+static int houghLine(const imImage* input, imImage* output, int counter)
+{
+ int ixsize, iysize, ixhalf, iyhalf, thetamax, x, y, rho, theta, rhomax;
+ imbyte *input_map = (imbyte*)input->data[0];
+ int *output_map = (int*)output->data[0];
+
+ ixsize = input->width;
+ iysize = input->height;
+ ixhalf = ixsize/2;
+ iyhalf = iysize/2;
+
+ thetamax = output->width; /* theta max = 180 */
+ rhomax = output->height/2; /* rho shift to 0, -rmax <= r <= +rmax */
+
+ costab = (double*)malloc(thetamax*sizeof(double));
+ sintab = (double*)malloc(thetamax*sizeof(double));
+
+ for (theta=0; theta < thetamax; theta++)
+ {
+ double th = (M_PI*theta)/thetamax;
+ costab[theta] = cos(th);
+ sintab[theta] = sin(th);
+ }
+
+ for (y=0; y < iysize; y++)
+ {
+ for (x=0; x < ixsize; x++)
+ {
+ if (input_map[y*ixsize + x])
+ {
+ for (theta=0; theta < thetamax; theta++)
+ {
+ rho = imRound((x-ixhalf)*costab[theta] + (y-iyhalf)*sintab[theta]);
+ if (rho > rhomax) continue;
+ if (rho < -rhomax) continue;
+ output_map[(rho+rhomax)*thetamax + theta]++;
+ }
+ }
+ }
+
+ if (!imCounterInc(counter))
+ {
+ free(costab); costab = NULL;
+ free(sintab); sintab = NULL;
+ return 0;
+ }
+ }
+
+ free(costab); costab = NULL;
+ free(sintab); sintab = NULL;
+
+ return 1;
+}
+
+static listnode* findMaxima(const imImage* hough_points, int *line_count, const imImage* hough)
+{
+ int x, y, xsize, ysize, rhomax, offset, rho_delta = 0;
+ listnode* maxima = NULL, *cur_node = NULL;
+ point pt;
+ imbyte *map = (imbyte*)hough_points->data[0];
+ int *hough_map = NULL;
+
+ xsize = hough_points->width; /* X = theta */
+ ysize = hough_points->height; /* Y = rho */
+ rhomax = ysize/2;
+
+ if (hough)
+ {
+ hough_map = (int*)hough->data[0];
+ rho_delta = (int)(rhomax*tan(THETA_DELTA1));
+ }
+
+ for (y=0; y < ysize; y++)
+ {
+ for (x=0; x < xsize; x++)
+ {
+ offset = y*xsize + x;
+
+ if (map[offset])
+ {
+ pt.theta = x;
+ pt.rho = y-rhomax;
+
+ if (!maxima)
+ {
+ cur_node = maxima = listnew(&pt);
+ (*line_count)++;
+ }
+ else
+ {
+ if (hough_map)
+ {
+ listnode* old_node = cur_node;
+ pt.count = hough_map[offset];
+ cur_node = listadd_filtered(maxima, cur_node, &pt, rho_delta);
+ if (cur_node != old_node)
+ (*line_count)++;
+ }
+ else
+ {
+ cur_node = listadd(cur_node, &pt);
+ (*line_count)++;
+ }
+ }
+ }
+ }
+ }
+
+ return maxima;
+}
+
+#define SWAPINT(a, b) {int t = a; a = b; b = t; }
+
+static void drawLine(imImage* image, int theta, int rho)
+{
+ int xsize, ysize, xstart, xstop, ystart, ystop, xhalf, yhalf;
+ float a, b;
+ imbyte *map = (imbyte*)image->data[0];
+
+ xsize = image->width;
+ ysize = image->height;
+ xhalf = xsize/2;
+ yhalf = ysize/2;
+
+ if (theta == 0) /* vertical line */
+ {
+ int y;
+ if (rho+xhalf < 0 || rho+xhalf > xsize-1) return;
+ for (y=0; y < ysize; y++)
+ map[y*xsize + rho+xhalf]=254;
+
+ return;
+ }
+
+ if (theta == 90) /* horizontal line */
+ {
+ int x;
+ if (rho+yhalf < 0 || rho+yhalf > ysize-1) return;
+ for (x=0; x < xsize; x++)
+ map[(rho+yhalf)*xsize + x]=254;
+
+ return;
+ }
+
+ a = (float)(-costab[theta]/sintab[theta]);
+ b = (float)((rho + xhalf*costab[theta] + yhalf*sintab[theta])/sintab[theta]);
+
+ {
+ int x[2];
+ int y[2];
+ int c = 0;
+ int y1 = imRound(b); /* x = 0 */
+ int y2 = imRound(a*(xsize-1)+b); /* x = xsize-1 */
+
+ int x1 = imRound(-b/a); /* y = 0 */
+ int x2 = imRound((ysize-1-b)/a); /* y = ysize-1 */
+
+ if (y1 >= 0 && y1 < ysize)
+ {
+ y[c] = y1;
+ x[c] = 0;
+ c++;
+ }
+
+ if (y2 >= 0 && y2 < ysize)
+ {
+ y[c] = y2;
+ x[c] = xsize-1;
+ c++;
+ }
+
+ if (c < 2 && x1 >= 0 && x1 < xsize)
+ {
+ x[c] = x1;
+ y[c] = 0;
+ c++;
+ }
+
+ if (c < 2 && x2 >= 0 && x2 < xsize)
+ {
+ x[c] = x2;
+ y[c] = ysize-1;
+ c++;
+ }
+
+ if (c < 2) return;
+
+ ystart = y[0];
+ xstart = x[0];
+ ystop = y[1];
+ xstop = x[1];
+ }
+
+ {
+ int x, y;
+ if (45 <= theta && theta <= 135)
+ {
+ if (xstart > xstop)
+ SWAPINT(xstart, xstop);
+
+ for (x=xstart; x <= xstop; x++)
+ {
+ y = imRound(a*x + b);
+ if (y < 0) continue;
+ if (y > ysize-1) continue;
+ map[y*xsize + x]=254;
+ }
+ }
+ else
+ {
+ if (ystart > ystop)
+ SWAPINT(ystart, ystop);
+
+ for (y=ystart; y <= ystop; y++)
+ {
+ x = imRound((y-b)/a);
+ if (x < 0) continue;
+ if (x > xsize-1) continue;
+ map[y*xsize + x]=254;
+ }
+ }
+ }
+}
+
+int imProcessHoughLines(const imImage* image, imImage *NewImage)
+{
+ int counter = imCounterBegin("Hough Line Transform");
+ imCounterTotal(counter, image->height, "Processing...");
+
+ int ret = houghLine(image, NewImage, counter);
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static void DrawPoints(imImage *image, listnode* maxima)
+{
+ listnode* cur_node;
+ while (maxima)
+ {
+ cur_node = maxima;
+ drawLine(image, cur_node->pt.theta, cur_node->pt.rho);
+ maxima = cur_node->next;
+ free(cur_node);
+ }
+}
+
+static void ReplaceColor(imImage* NewImage)
+{
+ int i;
+ imbyte* map = (imbyte*)NewImage->data[0];
+
+ NewImage->color_space = IM_MAP;
+ NewImage->palette[254] = imColorEncode(255, 0, 0);
+
+ for (i = 0; i < NewImage->count; i++)
+ {
+ if (map[i] == 254)
+ map[i] = 255;
+ }
+}
+
+int imProcessHoughLinesDraw(const imImage* original_image, const imImage *hough, const imImage *hough_points, imImage *NewImage)
+{
+ int theta, line_count = 0;
+
+ if (original_image != NewImage)
+ imImageCopyData(original_image, NewImage);
+
+ listnode* maxima = findMaxima(hough_points, &line_count, hough);
+
+ ReplaceColor(NewImage);
+
+ costab = (double*)malloc(180*sizeof(double));
+ sintab = (double*)malloc(180*sizeof(double));
+
+ for (theta=0; theta < 180; theta++)
+ {
+ double th = (M_PI*theta)/180.;
+ costab[theta] = cos(th);
+ sintab[theta] = sin(th);
+ }
+
+ DrawPoints(NewImage, maxima);
+
+ free(costab); costab = NULL;
+ free(sintab); sintab = NULL;
+
+ return line_count;
+}
+
diff --git a/im/src/process/im_kernel.cpp b/im/src/process/im_kernel.cpp
new file mode 100755
index 0000000..d5e976e
--- /dev/null
+++ b/im/src/process/im_kernel.cpp
@@ -0,0 +1,293 @@
+/** \file
+ * \brief Kernel Generators
+ * Creates several known kernels
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_kernel.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_util.h"
+#include "im_image.h"
+#include "im_kernel.h"
+
+#include <stdlib.h>
+#include <memory.h>
+#include <assert.h>
+#include <math.h>
+
+
+static imImage* iKernelCreate(int w, int h, int* data, char* desc)
+{
+ imImage* kernel = imImageCreate(w, h, IM_GRAY, IM_INT);
+ int* kernel_data = (int*)kernel->data[0];
+ memcpy(kernel_data, data, kernel->size);
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)desc);
+ return kernel;
+}
+
+imImage* imKernelSobel(void)
+{
+ int kernel_data[3*3] = {
+ -1, -2, -1,
+ 0, 0, 0,
+ 1, 2, 1
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Sobel");
+}
+
+imImage* imKernelPrewitt(void)
+{
+ int kernel_data[3*3] = {
+ -1, -1, -1,
+ 0, 0, 0,
+ 1, 1, 1
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Prewitt");
+}
+
+imImage* imKernelKirsh(void)
+{
+ int kernel_data[3*3] = {
+ -3, -3, -3,
+ -3, 0, -3,
+ 5, 5, 5
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Kirsh");
+}
+
+imImage* imKernelLaplacian4(void)
+{
+ int kernel_data[3*3] = {
+ 0, -1, 0,
+ -1, 4, -1,
+ 0, -1, 0
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Laplacian4");
+}
+
+imImage* imKernelLaplacian8(void)
+{
+ int kernel_data[3*3] = {
+ -1, -1, -1,
+ -1, 8, -1,
+ -1, -1, -1
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Laplacian8");
+}
+
+imImage* imKernelLaplacian5x5(void)
+{
+ int kernel_data[5*5] = {
+ 0, -1, -1, -1, 0,
+ -1, 0, 1, 0, -1,
+ -1, 1, 8, 1, -1,
+ -1, 0, 1, 0, -1,
+ 0, -1, -1, -1, 0
+ };
+
+ return iKernelCreate(5, 5, kernel_data, "Laplacian5x5");
+}
+
+imImage* imKernelLaplacian7x7(void)
+{
+ int kernel_data[7*7] = {
+ -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 48, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1
+ };
+
+ return iKernelCreate(7, 7, kernel_data, "Laplacian7x7");
+}
+
+imImage* imKernelGradian3x3(void)
+{
+ int kernel_data[3*3] = {
+ 0, -1, 0,
+ 0, 1, 0,
+ 0, 0, 0
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Gradian3x3");
+}
+
+imImage* imKernelGradian7x7(void)
+{
+ int kernel_data[7*7] = {
+ 0, -1, -1, 0, 1, 1, 0,
+ -1, -2, -2, 0, 2, 2, 1,
+ -1, -2, -3, 0, 3, 2, 1,
+ -1, -2, -3, 0, 3, 2, 1,
+ -1, -2, -3, 0, 3, 2, 1,
+ -1, -2, -2, 0, 2, 2, 1,
+ 0, -1, -1, 0, 1, 1, 0
+ };
+
+ return iKernelCreate(7, 7, kernel_data, "Gradian7x7");
+}
+
+imImage* imKernelSculpt(void)
+{
+ int kernel_data[3*3] = {
+ 0, 0, 1,
+ 0, 0, 0,
+ -1, 0, 0
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Sculpt");
+}
+
+imImage* imKernelMean3x3(void)
+{
+ int kernel_data[3*3] = {
+ 1, 1, 1,
+ 1, 1, 1,
+ 1, 1, 1
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Mean3x3");
+}
+
+imImage* imKernelMean5x5(void)
+{
+ int kernel_data[5*5] = {
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ };
+
+ return iKernelCreate(5, 5, kernel_data, "Mean5x5");
+}
+
+imImage* imKernelCircularMean5x5(void)
+{
+ int kernel_data[5*5] = {
+ 0, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0
+ };
+
+ return iKernelCreate(5, 5, kernel_data, "CircularMean5x5");
+}
+
+imImage* imKernelMean7x7(void)
+{
+ int kernel_data[7*7] = {
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1
+ };
+
+ return iKernelCreate(7, 7, kernel_data, "Mean7x7");
+}
+
+imImage* imKernelCircularMean7x7(void)
+{
+ int kernel_data[7*7] = {
+ 0, 0, 1, 1, 1, 0, 0,
+ 0, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 0,
+ 0, 0, 1, 1, 1, 0, 0
+ };
+
+ return iKernelCreate(7, 7, kernel_data, "CircularMean7x7");
+}
+
+imImage* imKernelGaussian3x3(void)
+{
+ int kernel_data[3*3] = {
+ 1, 2, 1,
+ 2, 4, 2,
+ 1, 2, 1
+ };
+
+ return iKernelCreate(3, 3, kernel_data, "Gaussian3x3");
+}
+
+imImage* imKernelGaussian5x5(void)
+{
+ int kernel_data[5*5] = {
+ 1, 4, 6, 4, 1,
+ 4, 16, 24, 16, 4,
+ 6, 24, 36, 24, 6,
+ 4, 16, 24, 16, 4,
+ 1, 4, 6, 4, 1
+ };
+
+ return iKernelCreate(5, 5, kernel_data, "Gaussian5x5");
+}
+
+imImage* imKernelBarlett5x5(void)
+{
+ int kernel_data[5*5] = {
+ 1, 2, 3, 2, 1,
+ 2, 4, 6, 4, 2,
+ 3, 6, 9, 6, 3,
+ 2, 4, 6, 4, 2,
+ 1, 2, 3, 2, 1
+ };
+
+ return iKernelCreate(5, 5, kernel_data, "Barlett5x5");
+}
+
+imImage* imKernelTopHat5x5(void)
+{
+ int kernel_data[5*5] = {
+ 0, -1, -1, -1, 0,
+ -1, -1, 3, -1, -1,
+ -1, 3, 4, 3, -1,
+ -1, -1, 3, -1, -1,
+ 0, -1, -1, -1, 0
+ };
+
+ return iKernelCreate(5, 5, kernel_data, "TopHat5x5");
+}
+
+imImage* imKernelTopHat7x7(void)
+{
+ int kernel_data[7*7] = {
+ 0, 0, -1, -1, -1, 0, 0,
+ 0, -1, -1, -1, -1, -1, 0,
+ -1, -1, 3, 3, 3, -1, -1,
+ -1, -1, 3, 4, 3, -1, -1,
+ -1, -1, 3, 3, 3, -1, -1,
+ 0, -1, -1, -1, -1, -1, 0,
+ 0, 0, -1, -1, -1, 0, 0
+ };
+
+ return iKernelCreate(7, 7, kernel_data, "TopHat7x7");
+}
+
+imImage* imKernelEnhance(void)
+{
+ int kernel_data[5*5] = {
+ 0, -1, -2, -1, 0,
+ -1, -4, 0, -4, -1,
+ -2, 0, 40, 0, -2,
+ -1, -4, 0, -4, -1,
+ 0, -1, -2, -1, 0
+ };
+
+ return iKernelCreate(5, 5, kernel_data, "Enhance");
+}
+
diff --git a/im/src/process/im_logic.cpp b/im/src/process/im_logic.cpp
new file mode 100755
index 0000000..82e607d
--- /dev/null
+++ b/im/src/process/im_logic.cpp
@@ -0,0 +1,136 @@
+/** \file
+ * \brief Logical Arithmetic Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_logic.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+template <class T>
+static void DoBitwiseOp(T *map1, T *map2, T *map, int count, int op)
+{
+ int i;
+
+ switch(op)
+ {
+ case IM_BIT_AND:
+ for (i = 0; i < count; i++)
+ map[i] = map1[i] & map2[i];
+ break;
+ case IM_BIT_OR:
+ for (i = 0; i < count; i++)
+ map[i] = map1[i] | map2[i];
+ break;
+ case IM_BIT_XOR:
+ for (i = 0; i < count; i++)
+ map[i] = (T)~(map1[i] | map2[i]);
+ break;
+ }
+}
+
+void imProcessBitwiseOp(const imImage* src_image1, const imImage* src_image2, imImage* dst_image, int op)
+{
+ int count = src_image1->count*src_image1->depth;
+
+ switch(src_image1->data_type)
+ {
+ case IM_BYTE:
+ DoBitwiseOp((imbyte*)src_image1->data[0], (imbyte*)src_image2->data[0], (imbyte*)dst_image->data[0], count, op);
+ break;
+ case IM_USHORT:
+ DoBitwiseOp((imushort*)src_image1->data[0], (imushort*)src_image2->data[0], (imushort*)dst_image->data[0], count, op);
+ break;
+ case IM_INT:
+ DoBitwiseOp((int*)src_image1->data[0], (int*)src_image2->data[0], (int*)dst_image->data[0], count, op);
+ break;
+ }
+}
+
+template <class T>
+static void DoBitwiseNot(T *map1, T *map, int count)
+{
+ for (int i = 0; i < count; i++)
+ map[i] = ~map1[i];
+}
+
+static void DoBitwiseNotBin(imbyte *map1, imbyte *map, int count)
+{
+ for (int i = 0; i < count; i++)
+ map[i] = map1[i]? 0: 1;
+}
+
+void imProcessBitwiseNot(const imImage* src_image, imImage* dst_image)
+{
+ int count = src_image->count*src_image->depth;
+
+ if (dst_image->color_space == IM_BINARY)
+ {
+ DoBitwiseNotBin((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], count);
+ return;
+ }
+
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ DoBitwiseNot((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], count);
+ break;
+ case IM_USHORT:
+ DoBitwiseNot((imushort*)src_image->data[0], (imushort*)dst_image->data[0], count);
+ break;
+ case IM_INT:
+ DoBitwiseNot((int*)src_image->data[0], (int*)dst_image->data[0], count);
+ break;
+ }
+}
+
+void imProcessBitMask(const imImage* src_image, imImage* dst_image, unsigned char mask, int op)
+{
+ imbyte* src_map = (imbyte*)src_image->data[0];
+ imbyte* dst_map = (imbyte*)dst_image->data[0];
+ int i;
+ int count = dst_image->count * dst_image->depth;
+ switch(op)
+ {
+ case IM_BIT_AND:
+ for (i = 0; i < count; i++)
+ *dst_map++ = *src_map++ & mask;
+ break;
+ case IM_BIT_OR:
+ for (i = 0; i < count; i++)
+ *dst_map++ = *src_map++ | mask;
+ break;
+ case IM_BIT_XOR:
+ for (i = 0; i < count; i++)
+ *dst_map++ = (imbyte)~(*src_map++ | mask);
+ break;
+ }
+
+ if ((op == IM_BIT_XOR || op == IM_BIT_OR) && dst_image->color_space == IM_BINARY && mask > 1)
+ dst_image->color_space = IM_GRAY;
+}
+
+void imProcessBitPlane(const imImage* src_image, imImage* dst_image, int plane, int reset)
+{
+ imbyte mask = imbyte(0x01 << plane);
+ if (reset) mask = ~mask;
+ imbyte* src_map = (imbyte*)src_image->data[0];
+ imbyte* dst_map = (imbyte*)dst_image->data[0];
+ int count = dst_image->count * dst_image->depth;
+ for (int i = 0; i < count; i++)
+ {
+ if (reset)
+ *dst_map++ = *src_map & mask;
+ else
+ *dst_map++ = (*src_map & mask)? 1: 0;
+
+ src_map++;
+ }
+}
diff --git a/im/src/process/im_morphology_bin.cpp b/im/src/process/im_morphology_bin.cpp
new file mode 100755
index 0000000..9405ff6
--- /dev/null
+++ b/im/src/process/im_morphology_bin.cpp
@@ -0,0 +1,317 @@
+/** \file
+ * \brief Morphology Operations for Binary Images
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_morphology_bin.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_counter.h>
+
+#include "im_process_loc.h"
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+#include <math.h>
+
+static int DoBinMorphConvolve(imbyte *map, imbyte* new_map, int width, int height, const imImage* kernel, int counter, int hit_value, int miss_value)
+{
+ int *kernel_line;
+ int offset, new_offset, i, j, x, y;
+ int kh, kw, kh2, kw2, hit;
+
+ kh = kernel->height;
+ kw = kernel->width;
+ kh2 = kernel->height/2;
+ kw2 = kernel->width/2;
+
+ int* kernel_data = (int*)kernel->data[0];
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ hit = 1;
+
+ for(y = -kh2; y <= kh2 && hit; y++)
+ {
+ kernel_line = kernel_data + (y+kh2)*kernel->width;
+
+ if ((j + y < 0) || // pass the bottom border
+ (j + y >= height)) // pass the top border
+ offset = -1;
+ else
+ offset = (j + y) * width;
+
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if ((offset == -1) ||
+ (i + x < 0) || // pass the left border
+ (i + x >= width)) // pass the right border
+ {
+ if(kernel_line[x+kw2] != -1 && kernel_line[x+kw2] != 0) // 0 extension beyond borders
+ hit = 0;
+ }
+ else
+ {
+ if(kernel_line[x+kw2] != -1 && kernel_line[x+kw2] != map[offset + (i + x)])
+ hit = 0;
+ }
+ }
+ }
+
+ new_map[new_offset + i] = (imbyte)(hit? hit_value: miss_value);
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+int imProcessBinMorphConvolve(const imImage* src_image, imImage* dst_image, const imImage *kernel, int hit_white, int iter)
+{
+ int j, ret = 0, hit_value, miss_value;
+ void *tmp = NULL;
+ int counter;
+
+ if (hit_white)
+ {
+ hit_value = 1;
+ miss_value = 0;
+ }
+ else
+ {
+ hit_value = 0;
+ miss_value = 1;
+ }
+
+ counter = imCounterBegin("Binary Morphological Convolution");
+ const char* msg = (const char*)imImageGetAttribute(kernel, "Description", NULL, NULL);
+ if (!msg) msg = "Processing...";
+ imCounterTotal(counter, src_image->height*iter, msg);
+
+ if (iter > 1)
+ tmp = malloc(src_image->size);
+
+ for (j = 0; j < iter; j++)
+ {
+ if (j == 0)
+ ret = DoBinMorphConvolve((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], src_image->width, src_image->height, kernel, counter, hit_value, miss_value);
+ else
+ {
+ memcpy(tmp, dst_image->data[0], src_image->size);
+ ret = DoBinMorphConvolve((imbyte*)tmp, (imbyte*)dst_image->data[0], src_image->width, src_image->height, kernel, counter, hit_value, miss_value);
+ }
+
+ if (!ret)
+ break;
+ }
+
+ if (tmp) free(tmp);
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+int imProcessBinMorphErode(const imImage* src_image, imImage* dst_image, int kernel_size, int iter)
+{
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_INT);
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Erode");
+
+ int* kernel_data = (int*)kernel->data[0];
+ for(int i = 0; i < kernel->count; i++)
+ kernel_data[i] = 1;
+
+ int ret = imProcessBinMorphConvolve(src_image, dst_image, kernel, 1, iter);
+ imImageDestroy(kernel);
+ return ret;
+}
+
+int imProcessBinMorphDilate(const imImage* src_image, imImage* dst_image, int kernel_size, int iter)
+{
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_INT);
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Dilate");
+ // Kernel is all zeros
+ int ret = imProcessBinMorphConvolve(src_image, dst_image, kernel, 0, iter);
+ imImageDestroy(kernel);
+ return ret;
+}
+
+int imProcessBinMorphOpen(const imImage* src_image, imImage* dst_image, int kernel_size, int iter)
+{
+ imImage*temp = imImageClone(src_image);
+ if (!temp)
+ return 0;
+
+ if (!imProcessBinMorphErode(src_image, temp, kernel_size, iter)) {imImageDestroy(temp); return 0;}
+ if (!imProcessBinMorphDilate(temp, dst_image, kernel_size, iter)) {imImageDestroy(temp); return 0;}
+
+ imImageDestroy(temp);
+ return 1;
+}
+
+int imProcessBinMorphClose(const imImage* src_image, imImage* dst_image, int kernel_size, int iter)
+{
+ imImage*temp = imImageClone(src_image);
+ if (!temp)
+ return 0;
+
+ if (!imProcessBinMorphDilate(src_image, temp, kernel_size, iter)) {imImageDestroy(temp); return 0;}
+ if (!imProcessBinMorphErode(temp, dst_image, kernel_size, iter)) {imImageDestroy(temp); return 0;}
+
+ imImageDestroy(temp);
+ return 1;
+}
+
+int imProcessBinMorphOutline(const imImage* src_image, imImage* dst_image, int kernel_size, int iter)
+{
+ if (!imProcessBinMorphErode(src_image, dst_image, kernel_size, iter)) return 0;
+ imProcessArithmeticOp(src_image, dst_image, dst_image, IM_BIN_DIFF);
+ return 1;
+}
+
+/* Direction masks: */
+/* N S W E */
+static int masks[] = { 0200, 0002, 0040, 0010 };
+
+/* True if pixel neighbor map indicates the pixel is 8-simple and */
+/* not an end point and thus can be deleted. The neighborhood */
+/* map is defined as an integer of bits abcdefghi with a non-zero */
+/* bit representing a non-zero pixel. The bit assignment for the */
+/* neighborhood is: */
+/* */
+/* a b c */
+/* d e f */
+/* g h i */
+
+static unsigned char isdelete[512] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+static void DoThinImage(imbyte *map, int xsize, int ysize)
+{
+ int x, y; /* Pixel location */
+ int i; /* Pass index */
+ int pc = 0; /* Pass count */
+ int count = 1; /* Deleted pixel count */
+ int p, q; /* Neighborhood maps of adjacent cells */
+ imbyte *qb; /* Neighborhood maps of previous scanline */
+ int m; /* Deletion direction mask */
+
+ qb = (imbyte *) malloc(xsize);
+ qb[xsize-1] = 0; /* Used for lower-right pixel */
+
+ while ( count )
+ {
+ /* Scan src_image while deletions */
+ pc++;
+ count = 0;
+
+ for ( i = 0 ; i < 4 ; i++ )
+ {
+ m = masks[i];
+
+ /* Build initial previous scan buffer. */
+
+ p = map[0] != 0;
+ for (x = 0 ; x < xsize-1 ; x++)
+ {
+ p = ((p<<1)&0006) | (map[x+1] != 0);
+ qb[x] = (imbyte)p;
+ }
+
+ /* Scan src_image for pixel deletion candidates. */
+
+ for ( y = 0 ; y < ysize-1 ; y++ )
+ {
+ q = qb[0];
+ p = ((q<<3)&0110) | (map[(y+1)*xsize] != 0);
+
+ for ( x = 0 ; x < xsize-1 ; x++ )
+ {
+ q = qb[x];
+ p = ((p<<1)&0666) | ((q<<3)&0110) | (map[(y+1)*xsize + x+1] != 0);
+ qb[x] = (imbyte)p;
+
+ if (((p&m) == 0) && isdelete[p] )
+ {
+ count++;
+ map[y*xsize + x] = 0;
+ }
+ }
+
+ /* Process right edge pixel. */
+
+ p = (p<<1)&0666;
+ if ( (p&m) == 0 && isdelete[p] )
+ {
+ count++;
+ map[y*xsize + xsize-1] = 0;
+ }
+ }
+
+ /* Process bottom scan line. */
+
+ for ( x = 0 ; x < xsize ; x++ )
+ {
+ q = qb[x];
+ p = ((p<<1)&0666) | ((q<<3)&0110);
+
+ if ( (p&m) == 0 && isdelete[p] )
+ {
+ count++;
+ map[(ysize-1)*xsize + x] = 0;
+ }
+ }
+ }
+ }
+
+ free (qb);
+}
+
+void imProcessBinMorphThin(const imImage* src_image, imImage* dst_image)
+{
+ imImageCopyData(src_image, dst_image);
+ DoThinImage((imbyte*)dst_image->data[0], dst_image->width, dst_image->height);
+}
diff --git a/im/src/process/im_morphology_gray.cpp b/im/src/process/im_morphology_gray.cpp
new file mode 100755
index 0000000..c3c9d45
--- /dev/null
+++ b/im/src/process/im_morphology_gray.cpp
@@ -0,0 +1,231 @@
+/** \file
+ * \brief Morphology Operations for Gray Images
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_morphology_gray.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_counter.h>
+#include <im_convert.h>
+
+#include "im_process_loc.h"
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+#include <math.h>
+
+
+template <class T, class DT>
+static int DoGrayMorphConvolve(T *map, T* new_map, int width, int height, const imImage* kernel, int counter, int ismax, DT)
+{
+ DT value, *kernel_line, max = 0, min = 0;
+ int offset, new_offset, i, j, x, y, init;
+ int kh, kw, kh2, kw2;
+
+ kh = kernel->height;
+ kw = kernel->width;
+ kh2 = kernel->height/2;
+ kw2 = kernel->width/2;
+
+ DT* kernel_data = (DT*)kernel->data[0];
+
+ for(j = 0; j < height; j++)
+ {
+ new_offset = j * width;
+
+ for(i = 0; i < width; i++)
+ {
+ init = 0;
+
+ for(y = -kh2; y <= kh2; y++)
+ {
+ kernel_line = kernel_data + (y+kh2)*kw;
+
+ if ((j + y < 0) || // pass the bottom border
+ (j + y >= height)) // pass the top border
+ continue;
+ else
+ offset = (j + y) * width;
+
+ for(x = -kw2; x <= kw2; x++)
+ {
+ if (kernel_line[x+kw2] != -1)
+ {
+ if ((i + x < 0) || // pass the left border
+ (i + x >= width)) // pass the right border
+ continue;
+ else
+ value = kernel_line[x+kw2] + map[offset + (i + x)];
+
+ if (init == 0) // first time here for each pass
+ {
+ if (ismax)
+ max = value;
+ else
+ min = value;
+
+ init = 1;
+ }
+ else
+ {
+ if (ismax && value > max)
+ max = value;
+
+ if (!ismax && value < min)
+ min = value;
+ }
+ }
+ }
+ }
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T) == size_of)
+ {
+ if (ismax)
+ new_map[new_offset + i] = (T)IM_BYTECROP(max);
+ else
+ new_map[new_offset + i] = (T)IM_BYTECROP(min);
+ }
+ else
+ {
+ if (ismax)
+ new_map[new_offset + i] = (T)max;
+ else
+ new_map[new_offset + i] = (T)min;
+ }
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+int imProcessGrayMorphConvolve(const imImage* src_image, imImage* dst_image, const imImage *kernel, int ismax)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin("Gray Morphological Convolution");
+ const char* msg = (const char*)imImageGetAttribute(kernel, "Description", NULL, NULL);
+ if (!msg) msg = "Processing...";
+ imCounterTotal(counter, src_image->depth*src_image->height, msg);
+
+ imImage* fkernel = NULL;
+
+ if (src_image->data_type == IM_FLOAT && kernel->data_type != IM_FLOAT)
+ {
+ fkernel = imImageCreate(kernel->width, kernel->height, IM_GRAY, IM_FLOAT);
+ imConvertDataType(kernel, fkernel, 0, 0, 0, IM_CAST_DIRECT);
+ kernel = fkernel;
+ }
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoGrayMorphConvolve((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (int)0);
+ break;
+ case IM_USHORT:
+ ret = DoGrayMorphConvolve((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (int)0);
+ break;
+ case IM_INT:
+ ret = DoGrayMorphConvolve((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (int)0);
+ break;
+ case IM_FLOAT:
+ ret = DoGrayMorphConvolve((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (float)0);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ if (fkernel) imImageDestroy(fkernel);
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+int imProcessGrayMorphErode(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_INT);
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Erode");
+ // Kernel is all zeros
+ int ret = imProcessGrayMorphConvolve(src_image, dst_image, kernel, 0);
+ imImageDestroy(kernel);
+ return ret;
+}
+
+int imProcessGrayMorphDilate(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_INT);
+ imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Dilate");
+ // Kernel is all zeros
+ int ret = imProcessGrayMorphConvolve(src_image, dst_image, kernel, 1);
+ imImageDestroy(kernel);
+ return ret;
+}
+
+int imProcessGrayMorphOpen(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ imImage*temp = imImageClone(src_image);
+ if (!temp)
+ return 0;
+
+ if (!imProcessGrayMorphErode(src_image, temp, kernel_size)) {imImageDestroy(temp); return 0;}
+ if (!imProcessGrayMorphDilate(temp, dst_image, kernel_size)) {imImageDestroy(temp); return 0;}
+
+ imImageDestroy(temp);
+ return 1;
+}
+
+int imProcessGrayMorphClose(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ imImage*temp = imImageClone(src_image);
+ if (!temp)
+ return 0;
+
+ if (!imProcessGrayMorphDilate(src_image, temp, kernel_size)) {imImageDestroy(temp); return 0;}
+ if (!imProcessGrayMorphErode(temp, dst_image, kernel_size)) {imImageDestroy(temp); return 0;}
+
+ imImageDestroy(temp);
+ return 1;
+}
+
+int imProcessGrayMorphTopHat(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ if (!imProcessGrayMorphOpen(src_image, dst_image, kernel_size)) return 0;
+ imProcessArithmeticOp(src_image, dst_image, dst_image, IM_BIN_DIFF);
+ return 1;
+}
+
+int imProcessGrayMorphWell(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ if (!imProcessGrayMorphClose(src_image, dst_image, kernel_size)) return 0;
+ imProcessArithmeticOp(src_image, dst_image, dst_image, IM_BIN_DIFF);
+ return 1;
+}
+
+int imProcessGrayMorphGradient(const imImage* src_image, imImage* dst_image, int kernel_size)
+{
+ imImage*temp = imImageClone(src_image);
+ if (!temp)
+ return 0;
+
+ if (!imProcessGrayMorphDilate(src_image, temp, kernel_size)) {imImageDestroy(temp); return 0;}
+ if (!imProcessGrayMorphErode(src_image, dst_image, kernel_size)) {imImageDestroy(temp); return 0;}
+
+ imProcessArithmeticOp(temp, dst_image, dst_image, IM_BIN_DIFF);
+
+ imImageDestroy(temp);
+ return 1;
+}
+
diff --git a/im/src/process/im_quantize.cpp b/im/src/process/im_quantize.cpp
new file mode 100755
index 0000000..de78cf4
--- /dev/null
+++ b/im/src/process/im_quantize.cpp
@@ -0,0 +1,64 @@
+/** \file
+ * \brief Additional Image Quantization Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_quantize.cpp,v 1.2 2009/09/25 18:40:32 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_palette.h>
+#include <im_math.h>
+
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+
+void imProcessQuantizeRGBUniform(const imImage* src_image, imImage* dst_image, int dither)
+{
+ imbyte *dst_map=(imbyte*)dst_image->data[0],
+ *red_map=(imbyte*)src_image->data[0],
+ *green_map=(imbyte*)src_image->data[1],
+ *blue_map=(imbyte*)src_image->data[2];
+
+ imImageSetPalette(dst_image, imPaletteUniform(), 256);
+
+ for (int y = 0; y < src_image->height; y++)
+ {
+ for (int x = 0; x < src_image->width; x++)
+ {
+ if (dither)
+ *dst_map++ = (imbyte)imPaletteUniformIndexHalftoned(imColorEncode(*red_map++, *green_map++, *blue_map++), x, y);
+ else
+ *dst_map++ = (imbyte)imPaletteUniformIndex(imColorEncode(*red_map++, *green_map++, *blue_map++));
+ }
+ }
+}
+
+void imProcessQuantizeGrayUniform(const imImage* src_image, imImage* dst_image, int grays)
+{
+ int i, value;
+
+ imbyte *dst_map=(imbyte*)dst_image->data[0],
+ *src_map=(imbyte*)src_image->data[0];
+
+ imbyte re_map[256];
+ memset(re_map, 0, 256);
+
+ float factor = (float)grays/256.0f;
+ float factor256 = 256.0f/(float)grays;
+
+ for (i = 0; i < 256; i++)
+ {
+ value = imResample(i, factor);
+ value = imResample(value, factor256);
+ re_map[i] = (imbyte)IM_BYTECROP(value);
+ }
+
+ int total_count = src_image->count*src_image->depth;
+ for (i = 0; i < total_count; i++)
+ dst_map[i] = re_map[src_map[i]];
+}
diff --git a/im/src/process/im_render.cpp b/im/src/process/im_render.cpp
new file mode 100755
index 0000000..f5d296f
--- /dev/null
+++ b/im/src/process/im_render.cpp
@@ -0,0 +1,532 @@
+/** \file
+ * \brief Synthetic Image Render
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_render.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_counter.h>
+#include <im_math.h>
+
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <memory.h>
+#include <math.h>
+#include <time.h>
+
+static float iGetFactor(int data_type)
+{
+ if (data_type == IM_BYTE)
+ return 255.0f;
+ else if (data_type == IM_INT || data_type == IM_USHORT)
+ return 65535.0f;
+ else
+ return 1.0f;
+}
+
+template <class T>
+static int DoRenderCondOp(T *map, int width, int height, int d, imRenderCondFunc render_func, float* param, int counter)
+{
+ int offset, cond = 1;
+ T Value;
+
+ for(int y = 0; y < height; y++)
+ {
+ offset = y * width;
+
+ for(int x = 0; x < width; x++)
+ {
+ Value = (T)(render_func(x, y, d, &cond, param));
+ if (cond) map[offset + x] = Value;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+int imProcessRenderCondOp(imImage* image, imRenderCondFunc render_func, char* render_name, float* param)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin(render_name);
+ imCounterTotal(counter, image->depth*image->height, "Rendering...");
+
+ for (int d = 0; d < image->depth; d++)
+ {
+ switch(image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoRenderCondOp((imbyte*)image->data[d], image->width, image->height, d, render_func, param, counter);
+ break;
+ case IM_USHORT:
+ ret = DoRenderCondOp((imushort*)image->data[d], image->width, image->height, d, render_func, param, counter);
+ break;
+ case IM_INT:
+ ret = DoRenderCondOp((int*)image->data[d], image->width, image->height, d, render_func, param, counter);
+ break;
+ case IM_FLOAT:
+ ret = DoRenderCondOp((float*)image->data[d], image->width, image->height, d, render_func, param, counter);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+template <class T>
+static int DoRenderOp(T *map, int width, int height, int d, imRenderFunc render_func, float* param, int counter, int plus)
+{
+ int offset;
+
+ for(int y = 0; y < height; y++)
+ {
+ offset = y * width;
+
+ for(int x = 0; x < width; x++)
+ {
+ if (plus)
+ {
+ int size_of = sizeof(imbyte);
+ float value = map[offset + x] + render_func(x, y, d, param);
+ if (sizeof(T) == size_of)
+ map[offset + x] = (T)IM_BYTECROP(value);
+ else
+ map[offset + x] = (T)value;
+
+ }
+ else
+ map[offset + x] = (T)render_func(x, y, d, param);
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+int imProcessRenderOp(imImage* image, imRenderFunc render_func, char* render_name, float* param, int plus)
+{
+ int ret = 0;
+
+ int counter = imCounterBegin(render_name);
+ imCounterTotal(counter, image->depth*image->height, "Rendering...");
+
+ for (int d = 0; d < image->depth; d++)
+ {
+ switch(image->data_type)
+ {
+ case IM_BYTE:
+ ret = DoRenderOp((imbyte*)image->data[d], image->width, image->height, d, render_func, param, counter, plus);
+ break;
+ case IM_USHORT:
+ ret = DoRenderOp((imushort*)image->data[d], image->width, image->height, d, render_func, param, counter, plus);
+ break;
+ case IM_INT:
+ ret = DoRenderOp((int*)image->data[d], image->width, image->height, d, render_func, param, counter, plus);
+ break;
+ case IM_FLOAT:
+ ret = DoRenderOp((float*)image->data[d], image->width, image->height, d, render_func, param, counter, plus);
+ break;
+ }
+
+ if (!ret)
+ break;
+ }
+
+ imCounterEnd(counter);
+
+ return ret;
+}
+
+static float do_add_specklenoise(int, int, int, int *cond, float* param)
+{
+ float rnd = float(rand()) / RAND_MAX;
+ if (rnd < param[1])
+ {
+ *cond = 1;
+ return (rand() * param[0]) / RAND_MAX;
+ }
+ else
+ {
+ *cond = 0;
+ return 0;
+ }
+}
+
+int imProcessRenderAddSpeckleNoise(const imImage* src_image, imImage* dst_image, float percent)
+{
+ float param[2];
+ param[0] = iGetFactor(src_image->data_type);
+ param[1] = percent / 100.0f;
+ srand((unsigned)time(NULL));
+ imImageCopyData(src_image, dst_image);
+ return imProcessRenderCondOp(dst_image, do_add_specklenoise, "Add Speckle Noise", param);
+}
+
+static float do_add_gaussiannoise(int, int, int, float* param)
+{
+ float rnd, x1, x2;
+
+ do
+ {
+ x1 = float(rand()) / RAND_MAX; /* [0,1] */
+ x2 = float(rand()) / RAND_MAX; /* [0,1] */
+ x1 = 2*x1 - 1; /* [-1,1] */
+ x2 = 2*x2 - 1; /* [-1,1] */
+ rnd = x1*x1 + x2*x2;
+ } while( rnd >= 1 || rnd == 0);
+
+ rnd = (float)sqrt(-2 * log(rnd) / rnd) * x1;
+ return rnd * param[1] + param[0];
+}
+
+int imProcessRenderAddGaussianNoise(const imImage* src_image, imImage* dst_image, float mean, float stddev)
+{
+ float param[2];
+ param[0] = mean;
+ param[1] = stddev;
+ srand((unsigned)time(NULL));
+ imImageCopyData(src_image, dst_image);
+ return imProcessRenderOp(dst_image, do_add_gaussiannoise, "Add Gaussian Noise", param, 1);
+}
+
+static float do_add_uniformnoise(int, int, int, float* param)
+{
+ float rnd = float(rand()) / RAND_MAX;
+ rnd = 2*rnd - 1; /* [-1,1] */
+ return 1.7320508f * rnd * param[1] + param[0];
+}
+
+int imProcessRenderAddUniformNoise(const imImage* src_image, imImage* dst_image, float mean, float stddev)
+{
+ float param[2];
+ param[0] = mean;
+ param[1] = stddev;
+ srand((unsigned)time(NULL));
+ imImageCopyData(src_image, dst_image);
+ return imProcessRenderOp(dst_image, do_add_uniformnoise, "Add Uniform Noise", param, 1);
+}
+
+static float do_const(int, int, int d, float* param)
+{
+ return param[d];
+}
+
+int imProcessRenderConstant(imImage* image, float* value)
+{
+ return imProcessRenderOp(image, do_const, "Constant", value, 0);
+}
+
+static float do_noise(int, int, int, float* param)
+{
+ return (rand() * param[0]) / RAND_MAX;
+}
+
+int imProcessRenderRandomNoise(imImage* image)
+{
+ static float param[1];
+ param[0] = iGetFactor(image->data_type);
+ srand((unsigned)time(NULL));
+ return imProcessRenderOp(image, do_noise, "Random Noise", param, 0);
+}
+
+static float do_cosine(int x, int y, int, float* param)
+{
+ return float((cos(param[1]*(x-param[3])) * cos(param[2]*(y-param[4])) + param[5]) * param[0]);
+}
+
+int imProcessRenderCosine(imImage* image, float xperiod, float yperiod)
+{
+ float param[6];
+ param[0] = iGetFactor(image->data_type);
+
+ if (xperiod == 0.0f) param[1] = 0.0;
+ else param[1] = 2.0f * 3.1416f / xperiod;
+
+ if (yperiod == 0.0f) param[2] = 0.0;
+ else param[2] = 2.0f * 3.1416f / yperiod;
+
+ param[3] = image->width/2.0f;
+ param[4] = image->height/2.0f;
+
+ if (image->data_type < IM_FLOAT)
+ param[0] = param[0] / 2.0f;
+
+ if (image->data_type == IM_BYTE)
+ param[5] = 1.0f;
+ else
+ param[5] = 0.0f;
+
+ return imProcessRenderOp(image, do_cosine, "Cosine", param, 0);
+}
+
+static float do_gaussian(int x, int y, int, float* param)
+{
+ int xd = x - (int)param[2];
+ int yd = y - (int)param[3];
+ xd *= xd;
+ yd *= yd;
+ return float(exp((xd + yd)*param[1])*param[0]);
+}
+
+int imProcessRenderGaussian(imImage* image, float stddev)
+{
+ float param[4];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = -1.0f / (2.0f * stddev * stddev);
+ param[2] = image->width/2.0f;
+ param[3] = image->height/2.0f;
+ return imProcessRenderOp(image, do_gaussian, "Gaussian", param, 0);
+}
+
+static float do_lapgauss(int x, int y, int, float* param)
+{
+ int xd = x - (int)param[2];
+ int yd = y - (int)param[3];
+ xd *= xd;
+ yd *= yd;
+ xd += yd;
+ return float((xd - param[4])*exp(xd*param[1])*param[0]);
+}
+
+int imProcessRenderLapOfGaussian(imImage* image, float stddev)
+{
+ float param[5];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = -1.0f / (2.0f * stddev * stddev);
+ param[2] = image->width/2.0f;
+ param[3] = image->height/2.0f;
+ param[4] = 2.0f * stddev * stddev;
+ param[0] /= param[4];
+ return imProcessRenderOp(image, do_lapgauss, "Laplacian of Gaussian", param, 0);
+}
+
+static inline float sinc(float x)
+{
+ if (x == 0.0f)
+ return 1.0f;
+ else
+ return float(sin(x)/x);
+}
+
+static float do_sinc(int x, int y, int, float* param)
+{
+ return float((sinc((x - param[3])*param[1])*sinc((y - param[4])*param[2]) + param[5])*param[0]);
+}
+
+int imProcessRenderSinc(imImage* image, float xperiod, float yperiod)
+{
+ float param[6];
+ param[0] = iGetFactor(image->data_type);
+
+ if (xperiod == 0.0f) param[1] = 0.0;
+ else param[1] = 2.0f * 3.1416f / xperiod;
+
+ if (yperiod == 0.0f) param[2] = 0.0;
+ else param[2] = 2.0f * 3.1416f / yperiod;
+
+ param[3] = image->width/2.0f;
+ param[4] = image->height/2.0f;
+
+ if (image->data_type < IM_FLOAT)
+ param[0] = param[0] / 1.3f;
+
+ if (image->data_type == IM_BYTE)
+ param[5] = 0.3f;
+ else
+ param[5] = 0.0f;
+
+ return imProcessRenderOp(image, do_sinc, "Sinc", param, 0);
+}
+
+static float do_box(int x, int y, int, float* param)
+{
+ int xr = x - (int)param[3];
+ int yr = y - (int)param[4];
+ if (xr < -(int)param[1] || xr > (int)param[1] ||
+ yr < -(int)param[2] || yr > (int)param[2])
+ return 0;
+ else
+ return param[0];
+}
+
+int imProcessRenderBox(imImage* image, int width, int height)
+{
+ float param[5];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = width/2.0f;
+ param[2] = height/2.0f;
+ param[3] = image->width/2.0f;
+ param[4] = image->height/2.0f;
+ return imProcessRenderOp(image, do_box, "Box", param, 0);
+}
+
+static float do_ramp(int x, int y, int, float* param)
+{
+ if (param[3])
+ {
+ if (y < param[1])
+ return 0;
+ if (y > param[2])
+ return 0;
+
+ return (y-param[1])*param[0];
+ }
+ else
+ {
+ if (x < param[1])
+ return 0;
+ if (x > param[2])
+ return 0;
+
+ return (x-param[1])*param[0];
+ }
+}
+
+int imProcessRenderRamp(imImage* image, int start, int end, int dir)
+{
+ float param[4];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = (float)start;
+ param[2] = (float)end;
+ param[3] = (float)dir;
+ param[0] /= float(end-start);
+ return imProcessRenderOp(image, do_ramp, "Ramp", param, 0);
+}
+
+static inline int Tent(int t, int T)
+{
+ if (t < 0)
+ return (t + T);
+ else
+ return (T - t);
+}
+
+static float do_tent(int x, int y, int, float* param)
+{
+ int xr = x - (int)param[3];
+ int yr = y - (int)param[4];
+ if (xr < -(int)param[1] || xr > (int)param[1] ||
+ yr < -(int)param[2] || yr > (int)param[2])
+ return 0;
+ else
+ return Tent(xr, (int)param[1]) * Tent(yr, (int)param[2]) * param[0];
+}
+
+int imProcessRenderTent(imImage* image, int width, int height)
+{
+ float param[5];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = width/2.0f;
+ param[2] = height/2.0f;
+ param[0] /= param[1]*param[2];
+ param[3] = image->width/2.0f;
+ param[4] = image->height/2.0f;
+ return imProcessRenderOp(image, do_tent, "Tent", param, 0);
+}
+
+static float do_cone(int x, int y, int, float* param)
+{
+ int xr = x - (int)param[2];
+ int yr = y - (int)param[3];
+ int radius = imRound(sqrt((double)(xr*xr + yr*yr)));
+ if (radius > (int)param[1])
+ return 0;
+ else
+ return ((int)param[1] - radius)*param[0];
+}
+
+int imProcessRenderCone(imImage* image, int radius)
+{
+ float param[4];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = (float)radius;
+ param[0] /= param[1];
+ param[2] = image->width/2.0f;
+ param[3] = image->height/2.0f;
+ return imProcessRenderOp(image, do_cone, "Cone", param, 0);
+}
+
+static float do_wheel(int x, int y, int, float* param)
+{
+ int xr = x - (int)param[3];
+ int yr = y - (int)param[4];
+ int radius = imRound(sqrt((double)(xr*xr + yr*yr)));
+ if (radius < (int)param[1] || radius > (int)param[2])
+ return 0;
+ else
+ return param[0];
+}
+
+int imProcessRenderWheel(imImage* image, int int_radius, int ext_radius)
+{
+ float param[5];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = (float)int_radius;
+ param[2] = (float)ext_radius;
+ param[3] = image->width/2.0f;
+ param[4] = image->height/2.0f;
+ return imProcessRenderOp(image, do_wheel, "Wheel", param, 0);
+}
+
+static float do_grid(int x, int y, int, float* param)
+{
+ int xr = x - (int)param[3];
+ int yr = y - (int)param[4];
+ if (xr % (int)param[1] == 0 && yr % (int)param[2] == 0)
+ return param[0];
+ else
+ return 0;
+}
+
+int imProcessRenderGrid(imImage* image, int x_space, int y_space)
+{
+ float param[5];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = (float)x_space;
+ param[2] = (float)y_space;
+ param[3] = image->width/2.0f;
+ param[4] = image->height/2.0f;
+ return imProcessRenderOp(image, do_grid, "Grid", param, 0);
+}
+
+static float do_chessboard(int x, int y, int, float* param)
+{
+ int xr = x - (int)param[3];
+ int yr = y - (int)param[4];
+ int xp = xr % (int)param[1];
+ int yp = yr % (int)param[2];
+ int xc = (int)param[1]/2;
+ int yc = (int)param[2]/2;
+ if (xr < 0) xc = -xc;
+ if (yr < 0) yc = -yc;
+ if ((xp < xc && yp < yc) ||
+ (xp > xc && yp > yc))
+ return param[0];
+ else
+ return 0;
+}
+
+int imProcessRenderChessboard(imImage* image, int x_space, int y_space)
+{
+ float param[5];
+ param[0] = iGetFactor(image->data_type);
+ param[1] = (float)x_space*2;
+ param[2] = (float)y_space*2;
+ param[3] = image->width/2.0f;
+ param[4] = image->height/2.0f;
+ return imProcessRenderOp(image, do_chessboard, "Chessboard", param, 0);
+}
diff --git a/im/src/process/im_resize.cpp b/im/src/process/im_resize.cpp
new file mode 100755
index 0000000..ddf6e47
--- /dev/null
+++ b/im/src/process/im_resize.cpp
@@ -0,0 +1,332 @@
+/** \file
+ * \brief Image Resize
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_resize.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math.h>
+#include <im_complex.h>
+#include <im_counter.h>
+
+#include "im_process_loc.h"
+
+#include <stdlib.h>
+#include <memory.h>
+
+
+static inline void iResizeInverse(int x, int y, float *xl, float *yl, float x_invfactor, float y_invfactor)
+{
+ *xl = (x + 0.5f) * x_invfactor;
+ *yl = (y + 0.5f) * y_invfactor;
+}
+
+template <class DT, class DTU>
+static int iResize(int src_width, int src_height, const DT *src_map,
+ int dst_width, int dst_height, DT *dst_map,
+ DTU Dummy, int order, int counter)
+{
+ float xl, yl;
+ float x_invfactor = float(src_width)/float(dst_width);
+ float y_invfactor = float(src_height)/float(dst_height);
+
+ for (int y = 0; y < dst_height; y++)
+ {
+ for (int x = 0; x < dst_width; x++)
+ {
+ iResizeInverse(x, y, &xl, &yl, x_invfactor, y_invfactor);
+
+ // if inside the original image
+ if (xl > 0.0 && yl > 0.0 && xl < src_width && yl < src_height)
+ {
+ if (order == 1)
+ *dst_map = imBilinearInterpolation(src_width, src_height, src_map, xl, yl);
+ else if (order == 3)
+ *dst_map = imBicubicInterpolation(src_width, src_height, src_map, xl, yl, Dummy);
+ else
+ *dst_map = imZeroOrderInterpolation(src_width, src_height, src_map, xl, yl);
+ }
+
+ dst_map++;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+
+ return 1;
+}
+
+template <class DT, class DTU>
+static int iReduce(int src_width, int src_height, const DT *src_map,
+ int dst_width, int dst_height, DT *dst_map,
+ DTU Dummy, int order, int counter)
+{
+ float xl, yl;
+ float x_invfactor = float(src_width)/float(dst_width);
+ float y_invfactor = float(src_height)/float(dst_height);
+
+ iResizeInverse(1, 1, &xl, &yl, x_invfactor, y_invfactor);
+ float xl0 = xl, yl0 = yl;
+ iResizeInverse(2, 2, &xl, &yl, x_invfactor, y_invfactor);
+ float xl1 = xl, yl1 = yl;
+
+ float box_width = xl1 - xl0;
+ float box_height = yl1 - yl0;
+
+ for (int y = 0; y < dst_height; y++)
+ {
+ for (int x = 0; x < dst_width; x++)
+ {
+ iResizeInverse(x, y, &xl, &yl, x_invfactor, y_invfactor);
+
+ // if inside the original image
+ if (xl > 0.0 && yl > 0.0 && xl < src_width && yl < src_height)
+ {
+ if (order == 0)
+ *dst_map = imZeroOrderDecimation(src_width, src_height, src_map, xl, yl, box_width, box_height, Dummy);
+ else
+ *dst_map = imBilinearDecimation(src_width, src_height, src_map, xl, yl, box_width, box_height, Dummy);
+ }
+
+ dst_map++;
+ }
+
+ if (!imCounterInc(counter))
+ return 0;
+ }
+ return 1;
+}
+
+int imProcessReduce(const imImage* src_image, imImage* dst_image, int order)
+{
+ int ret = 0;
+ int counter = imCounterBegin("Reduce Size");
+ const char* int_msg = (order == 1)? "Bilinear Decimation": "Zero Order Decimation";
+ imCounterTotal(counter, src_image->depth*dst_image->height, int_msg);
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = iReduce(src_image->width, src_image->height, (const imbyte*)src_image->data[i],
+ dst_image->width, dst_image->height, (imbyte*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_USHORT:
+ ret = iReduce(src_image->width, src_image->height, (const imushort*)src_image->data[i],
+ dst_image->width, dst_image->height, (imushort*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_INT:
+ ret = iReduce(src_image->width, src_image->height, (const int*)src_image->data[i],
+ dst_image->width, dst_image->height, (int*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_FLOAT:
+ ret = iReduce(src_image->width, src_image->height, (const float*)src_image->data[i],
+ dst_image->width, dst_image->height, (float*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_CFLOAT:
+ ret = iReduce(src_image->width, src_image->height, (const imcfloat*)src_image->data[i],
+ dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i],
+ imcfloat(0,0), order, counter);
+ break;
+ }
+ }
+
+ imCounterEnd(counter);
+ return ret;
+}
+
+int imProcessResize(const imImage* src_image, imImage* dst_image, int order)
+{
+ int ret = 0;
+ int counter = imCounterBegin("Resize");
+ const char* int_msg = (order == 3)? "Bicubic Interpolation": (order == 1)? "Bilinear Interpolation": "Zero Order Interpolation";
+ imCounterTotal(counter, src_image->depth*dst_image->height, int_msg);
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ret = iResize(src_image->width, src_image->height, (const imbyte*)src_image->data[i],
+ dst_image->width, dst_image->height, (imbyte*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_USHORT:
+ ret = iResize(src_image->width, src_image->height, (const imushort*)src_image->data[i],
+ dst_image->width, dst_image->height, (imushort*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_INT:
+ ret = iResize(src_image->width, src_image->height, (const int*)src_image->data[i],
+ dst_image->width, dst_image->height, (int*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_FLOAT:
+ ret = iResize(src_image->width, src_image->height, (const float*)src_image->data[i],
+ dst_image->width, dst_image->height, (float*)dst_image->data[i],
+ float(0), order, counter);
+ break;
+ case IM_CFLOAT:
+ ret = iResize(src_image->width, src_image->height, (const imcfloat*)src_image->data[i],
+ dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i],
+ imcfloat(0,0), order, counter);
+ break;
+ }
+ }
+
+ imCounterEnd(counter);
+ return ret;
+}
+
+template <class DT>
+static void ReduceBy4(int src_width,
+ int src_height,
+ DT *src_map,
+ int dst_width,
+ int dst_height,
+ DT *dst_map)
+{
+ int x,y,yd,xd;
+ (void)dst_height;
+
+ // make an even size
+ int height = (src_height/2)*2;
+ int width = (src_width/2)*2;
+
+ for(y = 0 ; y < height ; y += 2)
+ {
+ yd = y/2;
+ for(x = 0 ; x < width ; x += 2)
+ {
+ xd = x/2;
+ dst_map[yd * dst_width + xd] = ((src_map[y * src_width + x] +
+ src_map[y * src_width + (x+1)] +
+ src_map[(y+1) * src_width + x] +
+ src_map[(y+1) * src_width + (x+1)])/4);
+ }
+ }
+}
+
+void imProcessReduceBy4(const imImage* src_image, imImage* dst_image)
+{
+ int i;
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ ReduceBy4(src_image->width, src_image->height, (imbyte*)src_image->data[i], dst_image->width, dst_image->height, (imbyte*)dst_image->data[i]);
+ break;
+ case IM_USHORT:
+ ReduceBy4(src_image->width, src_image->height, (imushort*)src_image->data[i], dst_image->width, dst_image->height, (imushort*)dst_image->data[i]);
+ break;
+ case IM_INT:
+ ReduceBy4(src_image->width, src_image->height, (int*)src_image->data[i], dst_image->width, dst_image->height, (int*)dst_image->data[i]);
+ break;
+ case IM_FLOAT:
+ ReduceBy4(src_image->width, src_image->height, (float*)src_image->data[i], dst_image->width, dst_image->height, (float*)dst_image->data[i]);
+ break;
+ case IM_CFLOAT:
+ ReduceBy4(src_image->width, src_image->height, (imcfloat*)src_image->data[i], dst_image->width, dst_image->height, (imcfloat*)dst_image->data[i]);
+ break;
+ }
+ }
+}
+
+void imProcessCrop(const imImage* src_image, imImage* dst_image, int xmin, int ymin)
+{
+ int type_size = imDataTypeSize(src_image->data_type);
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ imbyte *src_map = (imbyte*)src_image->data[i];
+ imbyte *dst_map = (imbyte*)dst_image->data[i];
+
+ for (int y = 0; y < dst_image->height; y++)
+ {
+ int src_offset = (y + ymin)*src_image->line_size + xmin*type_size;
+ int dst_offset = y*dst_image->line_size;
+
+ memcpy(&dst_map[dst_offset], &src_map[src_offset], dst_image->line_size);
+ }
+ }
+}
+
+void imProcessInsert(const imImage* src_image, const imImage* rgn_image, imImage* dst_image, int xmin, int ymin)
+{
+ int type_size = imDataTypeSize(src_image->data_type);
+ int dst_size1 = xmin*type_size;
+ int dst_size2 = src_image->line_size - (rgn_image->line_size + dst_size1);
+ int dst_offset2 = dst_size1+rgn_image->line_size;
+ int ymax = ymin+rgn_image->height-1;
+ int rgn_size = rgn_image->line_size;
+
+ if (dst_size2 < 0)
+ {
+ dst_size2 = 0;
+ rgn_size = src_image->line_size - dst_size1;
+ dst_offset2 = dst_size1+rgn_size;
+ }
+
+ if (ymax > src_image->height-1)
+ ymax = src_image->height-1;
+
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ imbyte *src_map = (imbyte*)src_image->data[i];
+ imbyte *rgn_map = (imbyte*)rgn_image->data[i];
+ imbyte *dst_map = (imbyte*)dst_image->data[i];
+
+ for (int y = 0; y < src_image->height; y++)
+ {
+ if (y < ymin || y > ymax)
+ {
+ memcpy(dst_map, src_map, src_image->line_size);
+ }
+ else
+ {
+ if (dst_size1)
+ memcpy(dst_map, src_map, dst_size1);
+
+ memcpy(dst_map + dst_size1, rgn_map, rgn_size);
+
+ if (dst_size2)
+ memcpy(dst_map + dst_offset2,
+ src_map + dst_offset2, dst_size2);
+
+ rgn_map += rgn_image->line_size;
+ }
+
+ src_map += src_image->line_size;
+ dst_map += dst_image->line_size;
+ }
+ }
+}
+
+void imProcessAddMargins(const imImage* src_image, imImage* dst_image, int xmin, int ymin)
+{
+ int type_size = imDataTypeSize(src_image->data_type);
+ for (int i = 0; i < src_image->depth; i++)
+ {
+ imbyte *dst_map = (imbyte*)dst_image->data[i];
+ imbyte *src_map = (imbyte*)src_image->data[i];
+
+ for (int y = 0; y < src_image->height; y++)
+ {
+ int src_offset = y*src_image->line_size;
+ int dst_offset = (y + ymin)*dst_image->line_size + xmin*type_size;
+
+ memcpy(&dst_map[dst_offset], &src_map[src_offset], src_image->line_size);
+ }
+ }
+}
+
diff --git a/im/src/process/im_statistics.cpp b/im/src/process/im_statistics.cpp
new file mode 100755
index 0000000..b9f086d
--- /dev/null
+++ b/im/src/process/im_statistics.cpp
@@ -0,0 +1,341 @@
+/** \file
+ * \brief Image Statistics Calculations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_statistics.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math_op.h>
+
+#include "im_process_ana.h"
+
+#include <stdlib.h>
+#include <memory.h>
+#include <math.h>
+
+static unsigned long count_map(const imImage* image)
+{
+ unsigned long histo[256];
+ int size = image->width * image->height;
+ imCalcHistogram((imbyte*)image->data[0], size, histo, 0);
+ unsigned long numcolor = 0;
+
+ for (int i = 0; i < 256; i++)
+ {
+ if(histo[i] != 0)
+ numcolor++;
+ }
+
+ return numcolor;
+}
+
+// will count also all the 3 components color spaces
+static unsigned long count_rgb(const imImage* image)
+{
+ imbyte *count = (imbyte*)calloc(sizeof(imbyte), 1 << 21 ); /* (2^24)/8=2^21 ~ 2Mb */
+ if (!count)
+ return (unsigned long)-1;
+
+ int size = image->width * image->height;
+ imbyte *red = (imbyte*)image->data[0];
+ imbyte *green = (imbyte*)image->data[1];
+ imbyte *blue = (imbyte*)image->data[2];
+
+ int index;
+ unsigned long numcolor = 0;
+
+ for(int i = 0; i < size; i++)
+ {
+ index = red[i] << 16 | green[i] << 8 | blue[i];
+
+ if(imDataBitGet(count, index) == 0)
+ numcolor++;
+
+ imDataBitSet(count, index, 1);
+ }
+
+ free(count);
+
+ return numcolor;
+}
+
+unsigned long imCalcCountColors(const imImage* image)
+{
+ if (imColorModeDepth(image->color_space) > 1)
+ return count_rgb(image);
+ else
+ return count_map(image);
+}
+
+void imCalcHistogram(const imbyte* map, int size, unsigned long* histo, int cumulative)
+{
+ int i;
+
+ memset(histo, 0, 256 * sizeof(unsigned long));
+
+ for (i = 0; i < size; i++)
+ histo[*map++]++;
+
+ if (cumulative)
+ {
+ /* make cumulative histogram */
+ for (i = 1; i < 256; i++)
+ histo[i] += histo[i-1];
+ }
+}
+
+void imCalcUShortHistogram(const imushort* map, int size, unsigned long* histo, int cumulative)
+{
+ int i;
+
+ memset(histo, 0, 65535 * sizeof(unsigned long));
+
+ for (i = 0; i < size; i++)
+ histo[*map++]++;
+
+ if (cumulative)
+ {
+ /* make cumulative histogram */
+ for (i = 1; i < 65535; i++)
+ histo[i] += histo[i-1];
+ }
+}
+
+void imCalcGrayHistogram(const imImage* image, unsigned long* histo, int cumulative)
+{
+ int i;
+
+ memset(histo, 0, 256 * sizeof(unsigned long));
+
+ if (image->color_space == IM_GRAY)
+ {
+ imbyte* map = (imbyte*)image->data[0];
+ for (i = 0; i < image->count; i++)
+ histo[*map++]++;
+ }
+ else if (image->color_space == IM_MAP || image->color_space == IM_BINARY)
+ {
+ imbyte* map = (imbyte*)image->data[0];
+ imbyte gray_map[256], r, g, b;
+
+ for (i = 0; i < image->palette_count; i++)
+ {
+ imColorDecode(&r, &g, &b, image->palette[i]);
+ gray_map[i] = (imbyte)((299*r + 587*g + 114*b) / 1000);
+ }
+
+ for (i = 0; i < image->count; i++)
+ {
+ int index = *map++;
+ histo[gray_map[index]]++;
+ }
+ }
+ else
+ {
+ imbyte gray;
+ imbyte* r = (imbyte*)image->data[0];
+ imbyte* g = (imbyte*)image->data[1];
+ imbyte* b = (imbyte*)image->data[2];
+ for (i = 0; i < image->count; i++)
+ {
+ gray = (imbyte)((299*(*r++) + 587*(*g++) + 114*(*b++)) / 1000);
+ histo[gray]++;
+ }
+ }
+
+ if (cumulative)
+ {
+ /* make cumulative histogram */
+ for (i = 1; i < 256; i++)
+ histo[i] += histo[i-1];
+ }
+}
+
+template <class T>
+static void DoStats(T* data, int count, imStats* stats)
+{
+ memset(stats, 0, sizeof(imStats));
+
+ stats->min = (float)data[0];
+ stats->max = (float)data[0];
+
+ for (int i = 0; i < count; i++)
+ {
+ if (data[i] < stats->min)
+ stats->min = (float)data[i];
+
+ if (data[i] > stats->max)
+ stats->max = (float)data[i];
+
+ if (data[i] > 0)
+ stats->positive++;
+
+ if (data[i] < 0)
+ stats->negative++;
+
+ if (data[i] == 0)
+ stats->zeros++;
+
+ stats->mean += (float)data[i];
+ stats->stddev += ((float)data[i])*((float)data[i]);
+ }
+
+ stats->mean /= float(count);
+ stats->stddev = (float)sqrt((stats->stddev - count * stats->mean*stats->mean)/(count-1.0));
+}
+
+void imCalcImageStatistics(const imImage* image, imStats* stats)
+{
+ int count = image->width * image->height;
+
+ for (int i = 0; i < image->depth; i++)
+ {
+ switch(image->data_type)
+ {
+ case IM_BYTE:
+ DoStats((imbyte*)image->data[i], count, &stats[i]);
+ break;
+ case IM_USHORT:
+ DoStats((imushort*)image->data[i], count, &stats[i]);
+ break;
+ case IM_INT:
+ DoStats((int*)image->data[i], count, &stats[i]);
+ break;
+ case IM_FLOAT:
+ DoStats((float*)image->data[i], count, &stats[i]);
+ break;
+ }
+ }
+}
+
+void imCalcHistogramStatistics(const imImage* image, imStats* stats)
+{
+ int image_size = image->width * image->height;
+ unsigned long histo[256];
+
+ for (int d = 0; d < image->depth; d++)
+ {
+ imCalcHistogram((imbyte*)image->data[d], image_size, histo, 0);
+ DoStats((unsigned long*)histo, 256, &stats[d]);
+ }
+}
+
+void imCalcHistoImageStatistics(const imImage* image, int* median, int* mode)
+{
+ unsigned long histo[256];
+
+ for (int d = 0; d < image->depth; d++)
+ {
+ int i;
+ imCalcHistogram((imbyte*)image->data[d], image->count, histo, 0);
+
+ unsigned long half = image->count/2;
+ unsigned long count = histo[0];
+ for (i = 1; i < 256; i++)
+ {
+ if (count > half)
+ {
+ median[d] = i-1;
+ break;
+ }
+
+ count += histo[i];
+ }
+
+ unsigned long max = histo[0];
+ for (i = 1; i < 256; i++)
+ {
+ if (max < histo[i])
+ max = histo[i];
+ }
+
+ int found_mode = 0;
+ for (i = 0; i < 256; i++)
+ {
+ if (histo[i] == max)
+ {
+ if (found_mode)
+ {
+ mode[d] = -1;
+ break;
+ }
+
+ mode[d] = i;
+ found_mode = 1;
+ }
+ }
+ }
+}
+
+float imCalcSNR(const imImage* image, const imImage* noise_image)
+{
+ imStats stats[3];
+ imCalcImageStatistics((imImage*)image, stats);
+
+ imStats noise_stats[3];
+ imCalcImageStatistics((imImage*)noise_image, noise_stats);
+
+ if (image->color_space == IM_RGB)
+ {
+ noise_stats[0].stddev += noise_stats[1].stddev;
+ noise_stats[0].stddev += noise_stats[2].stddev;
+ noise_stats[0].stddev /= 3;
+ stats[0].stddev += stats[1].stddev;
+ stats[0].stddev += stats[2].stddev;
+ stats[0].stddev /= 3;
+ }
+
+ if (noise_stats[0].stddev == 0)
+ return 0;
+
+ return float(20.*log10(stats[0].stddev / noise_stats[0].stddev));
+}
+
+template <class T>
+static float DoRMSOp(T *map1, T *map2, int count)
+{
+ float rmserror = 0.0f;
+ float diff;
+
+ for (int i = 0; i < count; i++)
+ {
+ diff = float(map1[i] - map2[i]);
+ rmserror += diff * diff;
+ }
+
+ return rmserror;
+}
+
+float imCalcRMSError(const imImage* image1, const imImage* image2)
+{
+ float rmserror = 0.0f;
+
+ int count = image1->count*image1->depth;
+
+ switch(image1->data_type)
+ {
+ case IM_BYTE:
+ rmserror = DoRMSOp((imbyte*)image1->data[0], (imbyte*)image2->data[0], count);
+ break;
+ case IM_USHORT:
+ rmserror = DoRMSOp((imushort*)image1->data[0], (imushort*)image2->data[0], count);
+ break;
+ case IM_INT:
+ rmserror = DoRMSOp((int*)image1->data[0], (int*)image2->data[0], count);
+ break;
+ case IM_FLOAT:
+ rmserror = DoRMSOp((float*)image1->data[0], (float*)image2->data[0], count);
+ break;
+ case IM_CFLOAT:
+ rmserror = DoRMSOp((float*)image1->data[0], (float*)image2->data[0], 2*count);
+ break;
+ }
+
+ rmserror = float(sqrt(rmserror / float((count * image1->depth))));
+
+ return rmserror;
+}
+
diff --git a/im/src/process/im_threshold.cpp b/im/src/process/im_threshold.cpp
new file mode 100755
index 0000000..4af72ee
--- /dev/null
+++ b/im/src/process/im_threshold.cpp
@@ -0,0 +1,391 @@
+/** \file
+ * \brief Threshold Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_threshold.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+
+#include "im_process_pon.h"
+#include "im_process_ana.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+#include <math.h>
+
+
+void imProcessSliceThreshold(const imImage* src_image, imImage* dst_image, int start_level, int end_level)
+{
+ float params[3];
+ params[0] = (float)start_level;
+ params[1] = (float)end_level;
+ params[2] = (float)1; /* binarize 0-255 */
+ imProcessToneGamut(src_image, dst_image, IM_GAMUT_SLICE, params);
+ imImageMakeBinary(dst_image); /* this compensates the returned values in IM_GAMUT_SLICE */
+}
+
+void imProcessThresholdByDiff(const imImage* image1, const imImage* image2, imImage* NewImage)
+{
+ imbyte *src_map1 = (imbyte*)image1->data[0];
+ imbyte *src_map2 = (imbyte*)image2->data[0];
+ imbyte *dst_map = (imbyte*)NewImage->data[0];
+ int size = image1->count;
+
+ for (int i = 0; i < size; i++)
+ {
+ if (*src_map1++ <= *src_map2++)
+ *dst_map++ = 0;
+ else
+ *dst_map++ = 1;
+ }
+}
+
+template <class T>
+static void doThreshold(T *src_map, imbyte *dst_map, int count, int level, int value)
+{
+ for (int i = 0; i < count; i++)
+ {
+ if (*src_map++ <= level)
+ *dst_map++ = 0;
+ else
+ *dst_map++ = (imbyte)value;
+ }
+}
+
+void imProcessThreshold(const imImage* src_image, imImage* dst_image, int level, int value)
+{
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ doThreshold((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->count, level, value);
+ break;
+ case IM_USHORT:
+ doThreshold((imushort*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->count, level, value);
+ break;
+ case IM_INT:
+ doThreshold((int*)src_image->data[0], (imbyte*)dst_image->data[0],
+ src_image->count, level, value);
+ break;
+ }
+}
+
+static int compare_int(const void *elem1, const void *elem2)
+{
+ int* v1 = (int*)elem1;
+ int* v2 = (int*)elem2;
+
+ if (*v1 < *v2)
+ return -1;
+
+ if (*v1 > *v2)
+ return 1;
+
+ return 0;
+}
+
+static int thresUniErr(unsigned char* band, int width, int height)
+{
+ int x, y, i, bottom, top, ant2x2, maks1, maks2, maks4, t;
+ int xsize, ysize, offset1, offset2;
+ double a, b, c, phi;
+ int g[4], tab1[256], tab2[256], tab4[256];
+
+ memset(tab1, 0, sizeof(int)*256);
+ memset(tab2, 0, sizeof(int)*256);
+ memset(tab4, 0, sizeof(int)*256);
+
+ xsize = width;
+ ysize = height;
+
+ if (xsize%2 != 0)
+ xsize--;
+
+ if (ysize%2 != 0)
+ ysize--;
+
+ /* examine all 2x2 neighborhoods */
+
+ for (y=0; y<ysize; y+=2)
+ {
+ offset1 = y*width;
+ offset2 = (y+1)*width;
+
+ for (x=0; x<xsize; x+=2)
+ {
+ g[0] = band[offset1 + x];
+ g[1] = band[offset1 + x+1];
+ g[2] = band[offset2 + x];
+ g[3] = band[offset2 + x+1];
+
+ /* Sorting */
+ qsort(g, 4, sizeof(int), compare_int);
+
+ /* Accumulating */
+ tab1[g[0]] += 1;
+ tab1[g[1]] += 1;
+ tab1[g[2]] += 1;
+ tab1[g[3]] += 1;
+
+ tab2[g[0]] +=3;
+ tab2[g[1]] +=2;
+ tab2[g[2]] +=1;
+
+ tab4[g[0]] +=1;
+ }
+ }
+
+ /* Summing */
+ for (i=254; i>=0; i--)
+ {
+ tab1[i] += tab1[i+1];
+ tab2[i] += tab2[i+1];
+ tab4[i] += tab4[i+1];
+ }
+
+ /* Tables are ready, find threshold */
+ bottom = 0; top = 255;
+ ant2x2 = (xsize/2)*(ysize/2);
+ maks1 = tab1[0]; /* = ant2x2 * 4; */
+ maks2 = tab2[0]; /* = ant2x2 * 6; */
+ maks4 = tab4[0]; /* = ant2x2; */
+
+ /* binary search */
+ t = 0;
+ while (bottom != top-1)
+ {
+ t = (int) ((bottom+top)/2);
+
+ /* Calculate probabilities */
+ a = (double) tab1[t+1]/maks1;
+ b = (double) tab2[t+1]/maks2;
+ c = (double) tab4[t+1]/maks4;
+
+ phi = sqrt((b*b - c) / (a*a - b));
+
+ if (phi> 1)
+ bottom = t;
+ else
+ top = t;
+ }
+
+ return t;
+}
+
+int imProcessUniformErrThreshold(const imImage* image, imImage* NewImage)
+{
+ int level = thresUniErr((imbyte*)image->data[0], image->width, image->height);
+ imProcessThreshold(image, NewImage, level, 1);
+ return level;
+}
+
+static void do_dither_error(imbyte* data1, imbyte* data2, int size, int t, int value)
+{
+ int i, error;
+ float scale = (float)(t/(255.0-t));
+
+ error = 0; /* always in [-127,127] */
+
+ for (i = 0; i < size; i++)
+ {
+ if ((int)(*data1 + error) > t)
+ {
+ error -= (int)(((int)255 - (int)*data1++)*scale);
+ *data2++ = (imbyte)value;
+ }
+ else
+ {
+ error += (int)*data1++;
+ *data2++ = (imbyte)0;
+ }
+ }
+}
+
+void imProcessDifusionErrThreshold(const imImage* image, imImage* NewImage, int level)
+{
+ int value = image->depth > 1? 255: 1;
+ int size = image->width * image->height;
+ for (int i = 0; i < image->depth; i++)
+ {
+ do_dither_error((imbyte*)image->data[i], (imbyte*)NewImage->data[i], size, level, value);
+ }
+}
+
+int imProcessPercentThreshold(const imImage* image, imImage* NewImage, float percent)
+{
+ unsigned long histo[256], cut;
+
+ cut = (int)((image->width * image->height * percent)/100.);
+
+ imCalcHistogram((imbyte*)image->data[0], image->width * image->height, histo, 1);
+
+ int i;
+ for (i = 0; i < 256; i++)
+ {
+ if (histo[i] > cut)
+ break;
+ }
+
+ int level = (i==0? 0: i==256? 254: i-1);
+
+ imProcessThreshold(image, NewImage, level, 1);
+ return level;
+}
+
+static int MaximizeDiscriminantFunction(double * p)
+{
+ double mi_255 = 0;
+ int k;
+ for (k=0; k<256; k++)
+ mi_255 += k*p[k];
+
+ int index = 0;
+ double max = 0;
+ double mi_k = 0;
+ double w_k = 0;
+ double value;
+ for (k=0; k<256; k++)
+ {
+ mi_k += k*p[k];
+ w_k += p[k];
+ value = ((w_k == 0) || (w_k == 1))? -1 : ((mi_255*w_k - mi_k)*(mi_255*w_k - mi_k))/(w_k*(1-w_k));
+ if (value >= max)
+ {
+ index = k;
+ max = value;
+ }
+ }
+
+ return index;
+}
+
+static unsigned char Otsu(const imImage *image)
+{
+ unsigned long histo[256];
+ imCalcHistogram((imbyte*)image->data[0], image->count, histo, 0);
+
+ double totalPixels = image->count;
+ double p[256];
+ for (int i=0; i<256; i++)
+ p[i] = histo[i]/totalPixels;
+
+ return (unsigned char)MaximizeDiscriminantFunction(p);
+}
+
+int imProcessOtsuThreshold(const imImage* image, imImage* NewImage)
+{
+ int level = Otsu(image);
+ imProcessThreshold(image, NewImage, level, 1);
+ return level;
+}
+
+int imProcessMinMaxThreshold(const imImage* image, imImage* NewImage)
+{
+ imStats stats;
+ imCalcImageStatistics(image, &stats);
+ int level = (int)((stats.max - stats.min)/2.0f);
+ imProcessThreshold(image, NewImage, level, 1);
+ return level;
+}
+
+void imProcessHysteresisThresEstimate(const imImage* image, int *low_thres, int *high_thres)
+{
+ unsigned long hist[256];
+ imCalcHistogram((imbyte*)image->data[0], image->count, hist, 0);
+
+ /* The high threshold should be > 80 or 90% of the pixels */
+ unsigned long cut = (int)(0.1*image->count);
+
+ int k = 255;
+ unsigned long count = hist[255];
+ while (count < cut)
+ {
+ k--;
+ count += hist[k];
+ }
+ *high_thres = k;
+
+ k=0;
+ while (hist[k]==0) k++;
+
+ *low_thres = (int)((*high_thres + k)/2.0) + k;
+}
+
+void imProcessHysteresisThreshold(const imImage* image, imImage* NewImage, int low_thres, int high_thres)
+{
+ imbyte *src_map = (imbyte*)image->data[0];
+ imbyte *dst_map = (imbyte*)NewImage->data[0];
+ int i, j, size = image->count;
+
+ for (i = 0; i < size; i++)
+ {
+ if (*src_map > high_thres)
+ *dst_map++ = 1;
+ else if (*src_map > low_thres)
+ *dst_map++ = 2; // mark for future replace
+ else
+ *dst_map++ = 0;
+
+ src_map++;
+ }
+
+ // now loop multiple times until there is no "2"s or no one was changed
+ dst_map = (imbyte*)NewImage->data[0];
+ int changed = 1;
+ while (changed)
+ {
+ changed = 0;
+ for (j=1; j<image->height-1; j++)
+ {
+ for (i=1; i<image->width-1; i++)
+ {
+ int offset = i+j*image->width;
+ if (dst_map[offset] == 2)
+ {
+ // if there is an edge neighbor mark this as edge too
+ if (dst_map[offset+1] == 1 || dst_map[offset-1] == 1 ||
+ dst_map[offset+image->width] == 1 || dst_map[offset-image->width] == 1 ||
+ dst_map[offset+image->width-1] == 1 || dst_map[offset+image->width+1] == 1 ||
+ dst_map[offset-image->width-1] == 1 || dst_map[offset-image->width+1] == 1)
+ {
+ dst_map[offset] = 1;
+ changed = 1;
+ }
+ }
+ }
+ }
+ }
+
+ // Clear the remaining "2"s
+ dst_map = (imbyte*)NewImage->data[0];
+ for (i = 0; i < size; i++)
+ {
+ if (*dst_map == 2)
+ *dst_map = 0;
+ dst_map++;
+ }
+}
+
+void imProcessLocalMaxThresEstimate(const imImage* image, int *thres)
+{
+ unsigned long hist[256];
+ imCalcHistogram((imbyte*)image->data[0], image->count, hist, 0);
+
+ int high_count = 0;
+ int index = 255;
+ while (high_count < 10 && index > 0)
+ {
+ if (hist[index] != 0)
+ high_count++;
+
+ index--;
+ }
+ *thres = index+1;
+}
+
diff --git a/im/src/process/im_tonegamut.cpp b/im/src/process/im_tonegamut.cpp
new file mode 100755
index 0000000..cf63350
--- /dev/null
+++ b/im/src/process/im_tonegamut.cpp
@@ -0,0 +1,322 @@
+/** \file
+ * \brief Tone Gamut Operations
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_tonegamut.cpp,v 1.1 2008/10/17 06:16:33 scuri Exp $
+ */
+
+
+#include <im.h>
+#include <im_util.h>
+#include <im_math.h>
+
+#include "im_process_pon.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+#include <math.h>
+
+
+template <class T>
+static inline T line_op(const T& v, const T& min, const T& max, const float& a, const float& b)
+{
+ float r = v * a + b;
+ if (r > (float)max) return max;
+ if (r < (float)min) return min;
+ return (T)r;
+}
+
+template <class T>
+static inline T normal_op(const T& v, const T& min, const T& range)
+{
+ return (T)(float(v - min) / float(range));
+}
+
+template <class T>
+static inline T zerostart_op(const T& v, const T& min)
+{
+ return (T)(v - min);
+}
+
+template <class T>
+static inline float invert_op(const T& v, const T& min, const T& range)
+{
+ return 1.0f - float(v - min) / float(range);
+}
+
+template <class T>
+static inline T solarize_op(const T& v, const T& level, const float& A, const float& B)
+{
+ if (v > level)
+ return (T)(v * A + B);
+ else
+ return v;
+}
+
+template <class T>
+static inline T slice_op(const T& v, const T& min, const T& max, const T& start, const T& end, int bin)
+{
+ if (v < start || v > end)
+ return min;
+ else
+ {
+ if (bin)
+ return max;
+ else
+ return v;
+ }
+}
+
+template <class T>
+static inline T tonecrop_op(const T& v, const T& start, const T& end)
+{
+ if (v < start)
+ return start;
+ if (v > end)
+ return end;
+ else
+ return v;
+}
+
+template <class T>
+static inline T expand_op(const T& v, const T& min, const T& max, const T& start, const float& norm)
+{
+ float r = (v - start)*norm + min;
+ if (r > (float)max) return max;
+ if (r < (float)min) return min;
+ return (T)r;
+}
+
+template <class T>
+static inline float norm_pow_op(const T& v, const T& min, const T& range, const float& gamma)
+{
+ return (float)pow(float(v - min) / float(range), gamma);
+}
+
+template <class T>
+static inline float norm_log_op(const T& v, const T& min, const T& range, const float& norm, const float& K)
+{
+ return (float)(log(K * float(v - min) / float(range) + 1) / norm);
+}
+
+template <class T>
+static inline float norm_exp_op(const T& v, const T& min, const T& range, const float& norm, const float& K)
+{
+ return (float)((exp(K * float(v - min) / float(range)) - 1) / norm);
+}
+
+template <class T>
+static void DoNormalizedUnaryOp(T *map, T *new_map, int count, int op, float *args)
+{
+ int i;
+ T min, max, range;
+
+ int size_of = sizeof(imbyte);
+ if (sizeof(T) == size_of)
+ {
+ min = 0;
+ max = 255;
+ }
+ else
+ {
+ imMinMax(map, count, min, max);
+
+ if (min == max)
+ {
+ max = min + 1;
+
+ if (min != 0)
+ min = min - 1;
+ }
+ }
+
+ range = max-min;
+
+ switch(op)
+ {
+ case IM_GAMUT_NORMALIZE:
+ {
+ if (min >= 0 && max <= 1)
+ {
+ for (i = 0; i < count; i++)
+ new_map[i] = (T)map[i];
+ }
+ else
+ {
+ for (i = 0; i < count; i++)
+ new_map[i] = normal_op(map[i], min, range);
+ }
+ break;
+ }
+ case IM_GAMUT_INVERT:
+ for (i = 0; i < count; i++)
+ new_map[i] = (T)(invert_op(map[i], min, range)*range + min);
+ break;
+ case IM_GAMUT_ZEROSTART:
+ for (i = 0; i < count; i++)
+ new_map[i] = (T)zerostart_op(map[i], min);
+ break;
+ case IM_GAMUT_SOLARIZE:
+ {
+ T level = (T)(((100 - args[0]) * range) / 100.0f + min);
+ float A = float(level - min) / float(level - max);
+ float B = float(level * range) / float(max - level);
+ for (i = 0; i < count; i++)
+ new_map[i] = solarize_op(map[i], level, A, B);
+ break;
+ }
+ case IM_GAMUT_POW:
+ for (i = 0; i < count; i++)
+ new_map[i] = (T)(norm_pow_op(map[i], min, range, args[0])*range + min);
+ break;
+ case IM_GAMUT_LOG:
+ {
+ float norm = float(log(args[0] + 1));
+ for (i = 0; i < count; i++)
+ new_map[i] = (T)(norm_log_op(map[i], min, range, norm, args[0])*range + min);
+ break;
+ }
+ case IM_GAMUT_EXP:
+ {
+ float norm = float(exp(args[0]) - 1);
+ for (i = 0; i < count; i++)
+ new_map[i] = (T)(norm_exp_op(map[i], min, range, norm, args[0])*range + min);
+ break;
+ }
+ case IM_GAMUT_SLICE:
+ {
+ if (args[0] > args[1]) { float tmp = args[1]; args[1] = args[0]; args[0] = tmp; }
+ if (args[1] > max) args[1] = (float)max;
+ if (args[0] < min) args[0] = (float)min;
+ for (i = 0; i < count; i++)
+ new_map[i] = slice_op(map[i], min, max, (T)args[0], (T)args[1], (int)args[2]);
+ break;
+ }
+ case IM_GAMUT_CROP:
+ {
+ if (args[0] > args[1]) { float tmp = args[1]; args[1] = args[0]; args[0] = tmp; }
+ if (args[1] > max) args[1] = (float)max;
+ if (args[0] < min) args[0] = (float)min;
+ for (i = 0; i < count; i++)
+ new_map[i] = tonecrop_op(map[i], (T)args[0], (T)args[1]);
+ break;
+ }
+ case IM_GAMUT_EXPAND:
+ {
+ if (args[0] > args[1]) { float tmp = args[1]; args[1] = args[0]; args[0] = tmp; }
+ if (args[1] > max) args[1] = (float)max;
+ if (args[0] < min) args[0] = (float)min;
+ float norm = float(max - min)/(args[1] - args[0]);
+ for (i = 0; i < count; i++)
+ new_map[i] = expand_op(map[i], min, max, (T)args[0], norm);
+ break;
+ }
+ case IM_GAMUT_BRIGHTCONT:
+ {
+ float bs = (args[0] * range) / 100.0f;
+ float a = (float)tan((45+args[1]*0.449999)/57.2957795);
+ float b = bs + (float)range*(1.0f - a)/2.0f;
+ for (i = 0; i < count; i++)
+ new_map[i] = line_op(map[i], min, max, a, b);
+ break;
+ }
+ }
+}
+
+void imProcessToneGamut(const imImage* src_image, imImage* dst_image, int op, float *args)
+{
+ int count = src_image->count*src_image->depth;
+
+ switch(src_image->data_type)
+ {
+ case IM_BYTE:
+ DoNormalizedUnaryOp((imbyte*)src_image->data[0], (imbyte*)dst_image->data[0], count, op, args);
+ break;
+ case IM_USHORT:
+ DoNormalizedUnaryOp((imushort*)src_image->data[0], (imushort*)dst_image->data[0], count, op, args);
+ break;
+ case IM_INT:
+ DoNormalizedUnaryOp((int*)src_image->data[0], (int*)dst_image->data[0], count, op, args);
+ break;
+ case IM_FLOAT:
+ DoNormalizedUnaryOp((float*)src_image->data[0], (float*)dst_image->data[0], count, op, args);
+ break;
+ }
+}
+
+void imProcessUnNormalize(const imImage* image, imImage* NewImage)
+{
+ int count = image->count*image->depth;
+
+ float* map = (float*)image->data[0];
+ imbyte* new_map = (imbyte*)NewImage->data[0];
+
+ for (int i = 0; i < count; i++)
+ {
+ if (map[i] > 1)
+ new_map[i] = (imbyte)255;
+ else if (map[i] < 0)
+ new_map[i] = (imbyte)0;
+ else
+ new_map[i] = (imbyte)(map[i]*255);
+ }
+}
+
+template <class T>
+static void DoDirectConv(T* map, imbyte* new_map, int count)
+{
+ for (int i = 0; i < count; i++)
+ {
+ if (map[i] > 255)
+ new_map[i] = (imbyte)255;
+ else if (map[i] < 0)
+ new_map[i] = (imbyte)0;
+ else
+ new_map[i] = (imbyte)(map[i]);
+ }
+}
+
+void imProcessDirectConv(const imImage* image, imImage* NewImage)
+{
+ int count = image->count*image->depth;
+
+ switch(image->data_type)
+ {
+ case IM_USHORT:
+ DoDirectConv((imushort*)image->data[0], (imbyte*)NewImage->data[0], count);
+ break;
+ case IM_INT:
+ DoDirectConv((int*)image->data[0], (imbyte*)NewImage->data[0], count);
+ break;
+ case IM_FLOAT:
+ DoDirectConv((float*)image->data[0], (imbyte*)NewImage->data[0], count);
+ break;
+ }
+}
+
+void imProcessNegative(const imImage* src_image, imImage* dst_image)
+{
+ if (src_image->color_space == IM_MAP)
+ {
+ unsigned char r, g, b;
+ for (int i = 0; i < src_image->palette_count; i++)
+ {
+ imColorDecode(&r, &g, &b, src_image->palette[i]);
+ r = ~r; g = ~g; b = ~b;
+ dst_image->palette[i] = imColorEncode(r, g, b);
+ }
+
+ imImageCopyData(src_image, dst_image);
+ }
+ else if (src_image->color_space == IM_BINARY)
+ {
+ imbyte* map1 = (imbyte*)src_image->data[0];
+ imbyte* map = (imbyte*)dst_image->data[0];
+ for (int i = 0; i < src_image->count; i++)
+ map[i] = map1[i]? 0: 1;
+ }
+ else
+ imProcessToneGamut(src_image, dst_image, IM_GAMUT_INVERT, NULL);
+}
diff --git a/im/src/tecmake_compact.mak b/im/src/tecmake_compact.mak
new file mode 100755
index 0000000..d4fe0af
--- /dev/null
+++ b/im/src/tecmake_compact.mak
@@ -0,0 +1,1170 @@
+#-------------------------------------------------------------------------#
+#- Tecmake (Compact Version) -#
+#- Generic Makefile to build applications and libraries at TeCGraf -#
+#- The user makefile usually has the name "config.mak". -#
+#-------------------------------------------------------------------------#
+
+# Tecmake Version
+VERSION = 3.19
+
+# First target
+.PHONY: build
+build: tecmake
+
+
+#---------------------------------#
+# System Variables Definitions
+
+# Base Defintions
+TEC_SYSNAME:=$(shell uname -s)
+TEC_SYSVERSION:=$(shell uname -r|cut -f1 -d.)
+TEC_SYSMINOR:=$(shell uname -r|cut -f2 -d.)
+TEC_SYSARCH:=$(shell uname -m)
+
+# Fixes
+ifeq ($(TEC_SYSNAME), SunOS)
+ TEC_SYSARCH:=$(shell uname -p)
+endif
+ifeq ($(TEC_SYSNAME), IRIX)
+ TEC_SYSARCH:=$(shell uname -p)
+endif
+ifeq ($(TEC_SYSNAME), FreeBSD)
+ TEC_SYSMINOR:=$(shell uname -r|cut -f2 -d.|cut -f1 -d-)
+endif
+ifeq ($(TEC_SYSNAME), AIX)
+ TEC_SYSVERSION:=$(shell uname -v)
+ TEC_SYSMINOR:=$(shell uname -r)
+ TEC_SYSARCH:=ppc
+endif
+ifeq ($(TEC_SYSNAME), Darwin)
+ TEC_SYSARCH:=$(shell uname -p)
+endif
+
+ifeq ($(TEC_SYSARCH), powerpc)
+ TEC_SYSARCH:=ppc
+endif
+ifeq ($(TEC_SYSARCH), i686)
+ TEC_SYSARCH:=x86
+endif
+ifeq ($(TEC_SYSARCH), i386)
+ TEC_SYSARCH:=x86
+endif
+ifeq ($(TEC_SYSARCH), x86_64)
+ TEC_SYSARCH:=x64
+endif
+
+# Compose
+TEC_SYSRELEASE:=$(TEC_SYSVERSION).$(TEC_SYSMINOR)
+TEC_UNAME:=$(TEC_SYSNAME)$(TEC_SYSVERSION)$(TEC_SYSMINOR)
+
+# Linux 2.4 and GCC 3.x
+ifeq ($(TEC_UNAME), Linux24)
+ GCCVER:=$(shell gcc -dumpversion|cut -f1 -d.)
+ ifeq ($(GCCVER), 3)
+ TEC_UNAME:=$(TEC_UNAME)g3
+ endif
+endif
+
+# Linux 2.6 and GCC 4.x
+ifeq ($(TEC_UNAME), Linux26)
+ GCCVER:=$(shell gcc -dumpversion|cut -f1 -d.)
+ ifeq ($(GCCVER), 4)
+ TEC_UNAME:=$(TEC_UNAME)g4
+ endif
+endif
+
+# Linux and PowerPC
+ifeq ($(TEC_SYSNAME), Linux)
+ ifeq ($(TEC_SYSARCH), ppc)
+ TEC_UNAME:=$(TEC_UNAME)ppc
+ endif
+endif
+
+# 64-bits Linux
+ifeq ($(TEC_SYSARCH), x64)
+ BUILD_64=Yes
+ TEC_UNAME:=$(TEC_UNAME)_64
+endif
+
+ifeq ($(TEC_SYSARCH), ia64)
+ BUILD_64=Yes
+ TEC_UNAME:=$(TEC_UNAME)_ia64
+endif
+
+# Solaris and Intel
+ifeq ($(TEC_SYSNAME), SunOS)
+ ifeq ($(TEC_SYSARCH) , x86)
+ TEC_UNAME:=$(TEC_UNAME)x86
+ endif
+endif
+
+# Darwin and Intel
+ifeq ($(TEC_SYSNAME), Darwin)
+ifeq ($(TEC_SYSARCH), x86)
+ TEC_UNAME:=$(TEC_UNAME)x86
+ endif
+endif
+
+# System Info
+.PHONY: sysinfo
+sysinfo:
+ @echo ''; echo 'Tecmake - System Info'
+ @echo 'TEC_SYSNAME = $(TEC_SYSNAME)'
+ @echo 'TEC_SYSVERSION = $(TEC_SYSVERSION)'
+ @echo 'TEC_SYSMINOR = $(TEC_SYSMINOR)'
+ @echo 'TEC_SYSARCH = $(TEC_SYSARCH)'
+ @echo 'TEC_UNAME = $(TEC_UNAME)'; echo ''
+
+#---------------------------------#
+# Directories Definitions
+PROJDIR = ..
+SRCDIR = .
+OBJROOT = $(PROJDIR)/obj
+
+
+#---------------------------------#
+# Byte Order and Word Size
+
+ifneq ($(findstring x86, $(TEC_SYSARCH)), )
+ TEC_BYTEORDER = TEC_LITTLEENDIAN
+else
+ifeq ($(TEC_SYSARCH), arm)
+ TEC_BYTEORDER = TEC_LITTLEENDIAN
+else
+ TEC_BYTEORDER = TEC_BIGENDIAN
+endif
+endif
+
+ifeq ($(TEC_SYSARCH), x64)
+ TEC_WORDSIZE = TEC_64
+else
+ifdef BUILD_64
+ TEC_WORDSIZE = TEC_64
+else
+ TEC_WORDSIZE = TEC_32
+endif
+endif
+
+# Itanium Exception
+ifeq ($(TEC_SYSARCH), ia64)
+ TEC_BYTEORDER = TEC_LITTLEENDIAN
+ TEC_WORDSIZE = TEC_64
+endif
+
+
+#---------------------------------#
+# Compilation Flags
+STDFLAGS := -Wall
+STDDEFS := -DTEC_UNAME=$(TEC_UNAME) -DTEC_SYSNAME=$(TEC_SYSNAME) -D$(TEC_SYSNAME)=$(TEC_SYSRELEASE) -D$(TEC_BYTEORDER) -D$(TEC_WORDSIZE) -DFUNCPROTO=15
+STDINCS :=
+OPTFLAGS := -O2
+STDLFLAGS := r
+DEBUGFLAGS := -g
+STDLDFLAGS := -shared
+DLIBEXT := so
+
+ifneq ($(findstring Linux, $(TEC_UNAME)), )
+ GTK_DEFAULT = Yes
+endif
+ifneq ($(findstring Darwin, $(TEC_UNAME)), )
+ GTK_DEFAULT = Yes
+endif
+ifneq ($(findstring FreeBSD, $(TEC_UNAME)), )
+ GTK_DEFAULT = Yes
+endif
+ifneq ($(findstring Linux24, $(TEC_UNAME)), )
+ GTK_DEFAULT :=
+endif
+
+#---------------------------------#
+# Build Tools
+
+CC := $(TEC_TOOLCHAIN)gcc
+CPPC := $(TEC_TOOLCHAIN)g++
+FF := $(TEC_TOOLCHAIN)g77
+RANLIB := $(TEC_TOOLCHAIN)ranlib
+AR := $(TEC_TOOLCHAIN)ar
+DEBUGGER := $(TEC_TOOLCHAIN)gdb
+RCC := $(TEC_TOOLCHAIN)windres
+LD := $(TEC_TOOLCHAIN)gcc
+
+ifeq ($(TEC_UNAME), gcc2)
+ ifdef USE_GCC_2
+ CC := $(CC)-2
+ CPPC := $(CPPC)-2
+ FF := $(FF)-2
+ endif
+endif
+
+
+#---------------------------------#
+# User Configuration File
+
+MAKENAME = config.mak
+
+ifdef MF
+ MAKENAME = $(MF).mak
+endif
+
+###################
+include $(MAKENAME)
+###################
+
+
+#---------------------------------#
+# Definitions of public variables
+
+ifdef LIBNAME
+ TARGETNAME = $(LIBNAME)
+ MAKETYPE = LIB
+else
+ TARGETNAME = $(APPNAME)
+ MAKETYPE = APP
+endif
+
+ifndef TARGETNAME
+ $(error LIBNAME nor APPNAME defined in $(MAKENAME))
+endif
+
+PROJNAME ?= $(TARGETNAME)
+
+DEPEND := $(TARGETNAME).dep
+
+ifdef DEPENDDIR
+ DEPEND := $(DEPENDDIR)/$(TARGETNAME).dep.$(TEC_UNAME)
+endif
+
+SRCLUADIR ?= $(SRCDIR)
+LOHDIR ?= $(SRCLUADIR)
+
+ifeq ($(MAKETYPE), APP)
+ TARGETROOT ?= $(PROJDIR)/bin
+else
+ TARGETROOT ?= $(PROJDIR)/lib
+endif
+
+ifneq ($(PROJNAME), $(TARGETNAME))
+ OBJROOT := $(OBJROOT)/$(TARGETNAME)
+endif
+
+ifdef DBG
+ STDFLAGS += $(DEBUGFLAGS)
+ STDDEFS += -DDEBUG
+else
+ STDDEFS += -DNDEBUG
+ ifdef OPT
+ STDFLAGS += $(OPTFLAGS)
+ ifeq ($(findstring gcc, $(TEC_UNAME)), )
+ STRIP ?= Yes
+ endif
+ endif
+endif
+
+ifdef BUILD_64
+ ifneq ($(findstring SunOS, $(TEC_UNAME)), )
+ USE_CC = Yes
+ BUILD_64_DIR = Yes
+ endif
+ ifneq ($(findstring AIX, $(TEC_UNAME)), )
+ USE_CC = Yes
+ BUILD_64_DIR = Yes
+ endif
+ ifneq ($(findstring IRIX, $(TEC_UNAME)), )
+ USE_CC = Yes
+ BUILD_64_DIR = Yes
+ endif
+endif
+
+ifdef USE_CC
+ CC := cc
+ CPPC := CC
+ STDFLAGS =
+ ifdef USE_CC_DIR
+ TEC_UNAME := $(TEC_UNAME)cc
+ endif
+endif
+
+ifdef BUILD_64
+ ifdef BUILD_64_DIR
+ TEC_UNAME := $(TEC_UNAME)_64
+ endif
+endif
+
+ifneq ($(findstring gcc, $(TEC_UNAME)), )
+ ifeq ($(MAKETYPE), APP)
+ TEC_UNAME_DIR ?= $(TEC_SYSNAME)
+ endif
+endif
+
+TEC_UNAME_DIR ?= $(TEC_UNAME)
+ifdef DBG
+ ifdef DBG_DIR
+ TEC_UNAME_DIR := $(TEC_UNAME_DIR)d
+ endif
+endif
+
+OBJDIR := $(OBJROOT)/$(TEC_UNAME_DIR)
+TARGETDIR := $(TARGETROOT)/$(TEC_UNAME_DIR)
+
+# Change linker if any C++ source
+ifndef LINKER
+ ifneq "$(findstring .cpp, $(SRC))" ""
+ LINKER := $(CPPC)
+ else
+ LINKER := $(CC)
+ endif
+endif
+
+
+#---------------------------------#
+# LO and LOH Suffix
+
+ifeq ($(TEC_BYTEORDER), TEC_BIGENDIAN)
+ ifeq ($(TEC_WORDSIZE), TEC_64)
+ LO_SUFFIX ?= _be64
+ else
+ LO_SUFFIX ?= _be32
+ endif
+else
+ ifeq ($(TEC_WORDSIZE), TEC_64)
+ LO_SUFFIX ?= _le64
+ else
+ LO_SUFFIX ?=
+ endif
+endif
+
+
+#---------------------------------#
+# Platform specific variables
+
+# Definicoes para o X11
+X11_LIBS := Xmu Xt Xext X11
+#X11_LIB :=
+#X11_INC := #include <X11/X.h>
+
+# Definicoes para o OpenGL
+OPENGL_LIBS := GLU GL
+#OPENGL_LIB :=
+#OPENGL_INC := #include <GL/gl.h> and possibly
+MOTIFGL_LIB := GLw #include <GL/GLwMDrawA.h>
+
+# Definicoes para o Motif
+#MOTIF_LIB :=
+#MOTIF_INC := #include <Xm/Xm.h>
+
+# Definicoes para o GLUT
+#GLUT_LIB :=
+#GLUT_INC :=
+
+
+ifneq ($(findstring cygw, $(TEC_UNAME)), )
+ NO_DYNAMIC ?= Yes
+ ifdef BUILD_64
+ X11_LIB := /usr/X11R6/lib64
+ else
+ X11_LIB := /usr/X11R6/lib
+ endif
+ X11_INC := /usr/X11R6/include
+ MOTIFGL_LIB :=
+endif
+
+ifneq ($(findstring Linux, $(TEC_UNAME)), )
+ ifdef BUILD_64
+ ifeq ($(TEC_SYSARCH), ia64)
+ STDFLAGS += -fPIC
+ X11_LIB := /usr/X11R6/lib
+ else
+ STDFLAGS += -m64 -fPIC
+ X11_LIB := /usr/X11R6/lib64
+ endif
+ else
+ X11_LIB := /usr/X11R6/lib
+ endif
+ X11_INC := /usr/X11R6/include
+ MOTIFGL_LIB :=
+endif
+
+ifneq ($(findstring IRIX, $(TEC_UNAME)), ) # any IRIX
+ LD = ld
+ STDLDFLAGS := -elf -shared -rdata_shared -soname lib$(TARGETNAME).so
+ RANLIB := /bin/true
+ X11_LIBS := Xmu Xt X11
+ ifdef BUILD_64
+ ifdef USE_CC
+ STDFLAGS += -64 -KPIC
+ STDLDFLAGS += -64
+ LINKER += -64
+ endif
+ X11_LIB := /usr/lib64
+ MOTIF_LIB := /usr/Motif-2.1/lib64
+ else
+ X11_LIB := /usr/lib32
+ MOTIF_LIB := /usr/Motif-2.1/lib32
+ endif
+ MOTIF_INC = /usr/Motif-2.1/include
+endif
+
+ifneq ($(findstring AIX, $(TEC_UNAME)), )
+ NO_DYNAMIC ?= Yes
+ ifdef BUILD_64
+ ifdef USE_CC
+ STDFLAGS += -q64 # to compilers C and C++
+ STDLFLAGS := -X64 $(STDLFLAGS) # to librarian
+ STDLDFLAGS += -64
+ LINKER += -q64 # to linker
+ endif
+ endif
+endif
+
+ifneq ($(findstring HP-UX, $(TEC_UNAME)), )
+ NO_DYNAMIC ?= Yes
+ MOTIF_INC := /usr/include/Motif2.1
+ X11_LIBS := Xt Xext X11
+ OPENGL_LIB := /opt/graphics/OpenGL/lib
+ OPENGL_INC := /opt/graphics/OpenGL/include
+ STDDEFS := -DTEC_UNAME=$(TEC_UNAME) -DTEC_SYSNAME=$(TEC_SYSNAME) -D$(TEC_BYTEORDER) -D$(TEC_WORDSIZE) -DFUNCPROTO=15
+ CC := aCC
+ CPPC := aCC
+ LINKER := aCC
+endif
+
+ifneq ($(findstring SunOS, $(TEC_UNAME)), )
+ LD = ld
+ STDLDFLAGS := -G
+ X11_INC := /usr/openwin/share/include
+ X11_LIB := /usr/openwin/lib
+ MOTIF_INC := /usr/dt/share/include
+ MOTIF_LIB := /usr/dt/lib
+ OPENGL_INC := /usr/openwin/share/include/X11
+ GLUT_LIB := /usr/local/glut-3.7/lib/glut
+ GLUT_INC := /usr/local/glut-3.7/include
+ ifdef BUILD_64
+ ifdef USE_CC
+ STDFLAGS += -xarch=v9 -KPIC
+ # have to force these PATHs because of a conflict with standard PATHs
+ STDLDFLAGS += -64 -L/usr/lib/64 -L/usr/ucblib/sparcv9
+ LINKER += -xarch=v9
+ endif
+ endif
+endif
+
+ifneq ($(findstring Darwin, $(TEC_UNAME)), )
+ X11_LIBS := Xmu Xp Xt Xext X11
+ X11_LIB := /usr/X11R6/lib
+ X11_INC := /usr/X11R6/include
+ MOTIF_INC := /usr/OpenMotif/include
+ MOTIF_LIB := /usr/OpenMotif/lib
+ ifdef BUILD_DYLIB
+ STDLDFLAGS := -dynamiclib -install_name lib$(TARGETNAME).dylib
+ DLIBEXT := dylib
+ else
+ STDLDFLAGS := -bundle -undefined dynamic_lookup
+ endif
+endif
+
+ifneq ($(findstring FreeBSD, $(TEC_UNAME)), )
+ X11_LIB := /usr/X11R6/lib
+ X11_INC := /usr/X11R6/include
+endif
+
+
+################################
+# Allows an extra configuration file.
+ifdef EXTRA_CONFIG
+include $(EXTRA_CONFIG)
+endif
+################################
+
+
+#---------------------------------#
+# Tecgraf Libraries Location
+TECTOOLS_HOME ?= ../..
+
+IUP ?= $(TECTOOLS_HOME)/iup
+CD ?= $(TECTOOLS_HOME)/cd
+IM ?= $(TECTOOLS_HOME)/im
+LUA ?= $(TECTOOLS_HOME)/lua
+LUA51 ?= $(TECTOOLS_HOME)/lua5.1
+
+
+#---------------------------------#
+# Pre-defined libraries
+
+# Library order:
+# user + iupcd + cd + iup + motif + X
+# Library path order is the oposite
+
+ifdef USE_LUA
+ LUASUFX :=
+ LIBLUASUFX := 3
+endif
+
+ifdef USE_LUA4
+ LUASUFX := 4
+ LIBLUASUFX := 4
+ override USE_LUA = Yes
+ LUA := $(LUA4)
+endif
+
+ifdef USE_LUA5
+ LUASUFX := 5
+ LIBLUASUFX := 5
+ override USE_LUA = Yes
+ LUA := $(LUA5)
+endif
+
+ifdef USE_LUA50
+ LUASUFX := 50
+ LIBLUASUFX := 5
+ override USE_LUA = Yes
+ LUA := $(LUA50)
+ NO_LUALIB := Yes
+endif
+
+ifdef USE_LUA51
+ LUASUFX := 5.1
+ LIBLUASUFX := 51
+ override USE_LUA = Yes
+ LUA := $(LUA51)
+ NO_LUALIB := Yes
+endif
+
+ifdef USE_IUP3
+ override USE_IUP = Yes
+endif
+
+ifdef USE_IUP3BETA
+ IUP := $(IUP)3
+endif
+
+ifdef USE_IUPBETA
+ IUP := $(IUP)/beta
+endif
+
+ifdef USE_CDBETA
+ CD := $(CD)/beta
+endif
+
+ifdef USE_IMBETA
+ IM := $(IM)/beta
+endif
+
+ifdef USE_GLUT
+ override USE_OPENGL = Yes
+endif
+
+ifdef USE_IUPCONTROLS
+ override USE_CD = Yes
+ override USE_IUP = Yes
+ ifdef USE_IUPLUA
+ ifdef USE_STATIC
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiupluacontrols$(LIBLUASUFX).a
+ else
+ LIBS += iupluacontrols$(LIBLUASUFX)
+ endif
+ override USE_CDLUA = Yes
+ endif
+ ifdef USE_STATIC
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiupcontrols.a
+ else
+ LIBS += iupcontrols
+ endif
+endif
+
+ifdef USE_IMLUA
+ override USE_IM = Yes
+ ifdef USE_STATIC
+ SLIB += $(IM)/lib/$(TEC_UNAME)/libimlua$(LIBLUASUFX).a
+ else
+ LIBS += imlua$(LIBLUASUFX)
+ endif
+endif
+
+ifdef USE_CDLUA
+ override USE_CD = Yes
+ ifdef USE_STATIC
+ ifdef USE_IUP
+ ifdef USE_OLDNAMES
+ SLIB += $(CD)/lib/$(TEC_UNAME)/libcdluaiup$(LIBLUASUFX).a
+ endif
+ endif
+ SLIB += $(CD)/lib/$(TEC_UNAME)/libcdlua$(LIBLUASUFX).a
+ else
+ ifdef USE_IUP
+ ifdef USE_OLDNAMES
+ LIBS += cdluaiup$(LIBLUASUFX)
+ endif
+ endif
+ LIBS += cdlua$(LIBLUASUFX)
+ endif
+endif
+
+ifdef USE_IUPLUA
+ override USE_IUP = Yes
+ ifdef USE_STATIC
+ ifdef USE_CD
+ ifndef USE_OLDNAMES
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiupluacd$(LIBLUASUFX).a
+ endif
+ endif
+ ifdef USE_OPENGL
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiupluagl$(LIBLUASUFX).a
+ endif
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiuplua$(LIBLUASUFX).a
+ else
+ ifdef USE_CD
+ ifndef USE_OLDNAMES
+ LIBS += iupluacd$(LIBLUASUFX)
+ endif
+ endif
+ ifdef USE_OPENGL
+ LIBS += iupluagl$(LIBLUASUFX)
+ endif
+ LIBS += iuplua$(LIBLUASUFX)
+ endif
+endif
+
+ifdef USE_LUA
+ LUA_LIB ?= $(LUA)/lib/$(TEC_UNAME)
+ ifdef USE_STATIC
+ ifndef NO_LUALIB
+ SLIB += $(LUA_LIB)/liblualib$(LUASUFX).a
+ endif
+ SLIB += $(LUA_LIB)/liblua$(LUASUFX).a
+ else
+ ifndef NO_LUALIB
+ LIBS += lualib$(LUASUFX)
+ endif
+ ifndef NO_LUALINK
+ LIBS += lua$(LUASUFX)
+ LDIR += $(LUA_LIB)
+ endif
+ endif
+
+ LUA_INC ?= $(LUA)/include
+ INCLUDES += $(LUA_INC)
+
+ LUA_BIN ?= $(LUA)/bin/$(TEC_UNAME)
+ BIN2C := $(LUA_BIN)/bin2c$(LUASUFX)
+ LUAC := $(LUA_BIN)/luac$(LUASUFX)
+ LUABIN := $(LUA_BIN)/lua$(LUASUFX)
+endif
+
+ifdef USE_IUP
+ IUPSUFX :=
+ ifdef USE_IUP3
+ ifdef GTK_DEFAULT
+ ifdef USE_MOTIF
+ IUPSUFX := mot
+ else
+ override USE_GTK = Yes
+ endif
+ else
+ ifdef USE_GTK
+ IUPSUFX := gtk
+ else
+ override USE_MOTIF = Yes
+ endif
+ endif
+ else
+ override USE_MOTIF = Yes
+ endif
+ ifdef USE_STATIC
+ ifdef USE_CD
+ ifndef USE_OLDNAMES
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiupcd.a
+ endif
+ endif
+ ifdef USE_OPENGL
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiupgl.a
+ endif
+ SLIB += $(IUP)/lib/$(TEC_UNAME)/libiup$(IUPSUFX).a
+ else
+ ifdef USE_CD
+ ifndef USE_OLDNAMES
+ LIBS += iupcd
+ endif
+ endif
+ ifdef USE_OPENGL
+ LIBS += iupgl
+ endif
+ LIBS += iup$(IUPSUFX)
+ LDIR += $(IUP)/lib/$(TEC_UNAME)
+ endif
+ INCLUDES += $(IUP)/include
+endif
+
+ifdef USE_CD
+ override USE_X11 = Yes
+ ifdef USE_STATIC
+ ifdef USE_IUP
+ ifdef USE_OLDNAMES
+ SLIB += $(CD)/lib/$(TEC_UNAME)/libcdiup.a
+ endif
+ endif
+ ifdef USE_XRENDER
+ ifdef USE_OLDNAMES
+ SLIB += $(CD)/lib/$(TEC_UNAME)/libcdxrender.a
+ else
+ SLIB += $(CD)/lib/$(TEC_UNAME)/libcdcontextplus.a
+ endif
+ endif
+ SLIB += $(CD)/lib/$(TEC_UNAME)/libcd.a
+ ifdef USE_XRENDER
+ LIBS += Xrender Xft
+ else
+ ifndef USE_GTK
+ ifndef USE_OLDNAMES
+ # Freetype is included in GTK
+ SLIB += $(CD)/lib/$(TEC_UNAME)/libfreetype.a
+ endif
+ endif
+ endif
+ else
+ ifdef USE_XRENDER
+ ifdef USE_OLDNAMES
+ LIBS += cdxrender
+ else
+ LIBS += cdcontextplus
+ endif
+ endif
+ LIBS += cd
+ LDIR += $(CD)/lib/$(TEC_UNAME)
+ ifdef USE_XRENDER
+ LIBS += Xrender Xft
+ else
+ ifndef USE_GTK
+ ifndef USE_OLDNAMES
+ # Freetype is included in GTK
+ LIBS += freetype
+ endif
+ endif
+ endif
+ endif
+ INCLUDES += $(CD)/include
+endif
+
+ifdef USE_IM
+ ifdef USE_STATIC
+ SLIB += $(IM)/lib/$(TEC_UNAME)/libim.a
+ else
+ LIBS += im
+ LDIR += $(IM)/lib/$(TEC_UNAME)
+ endif
+ INCLUDES += $(IM)/include
+endif
+
+# All except gcc in Windows (Cygwin)
+ifeq ($(findstring gcc, $(TEC_UNAME)), )
+
+ifdef USE_GLUT
+ LIBS += glut
+ LDIR += $(GLUT_LIB)
+ STDINCS += $(GLUT_INC)
+endif
+
+ifdef USE_OPENGL
+ override USE_X11 = Yes
+ ifdef USE_MOTIF
+ LIBS += $(MOTIFGL_LIB)
+ endif
+ LIBS += $(OPENGL_LIBS)
+ LDIR += $(OPENGL_LIB)
+ STDINCS += $(OPENGL_INC)
+endif
+
+ifdef USE_MOTIF
+ override USE_X11 = Yes
+ LIBS += Xm
+ LDIR += $(MOTIF_LIB)
+ STDINCS += $(MOTIF_INC)
+ ifneq ($(findstring Linux, $(TEC_UNAME)), )
+ X11_LIBS := Xpm $(X11_LIBS)
+ endif
+ ifneq ($(findstring cygw, $(TEC_UNAME)), )
+ X11_LIBS := Xpm $(X11_LIBS)
+ endif
+endif
+
+ifdef USE_GTK
+# ifneq ($(findstring Darwin, $(TEC_UNAME)), )
+# STDINCS += /Library/Frameworks/Gtk.framework/Headers
+# STDINCS += /Library/Frameworks/GLib.framework/Headers
+# STDINCS += /Library/Frameworks/Cairo.framework/Headers
+# LFLAGS += -framework Gtk
+# else
+ ifneq ($(findstring Darwin, $(TEC_UNAME)), )
+ GTK_BASE := /sw
+ LDIR += /sw/lib
+ LIBS += freetype
+ else
+ GTK_BASE := /usr
+ endif
+ override USE_X11 = Yes
+ LIBS += gtk-x11-2.0 gdk-x11-2.0 gdk_pixbuf-2.0 pango-1.0 pangox-1.0 gobject-2.0 gmodule-2.0 glib-2.0
+ STDINCS += $(GTK_BASE)/include/atk-1.0 $(GTK_BASE)/include/gtk-2.0 $(GTK_BASE)/include/cairo $(GTK_BASE)/include/pango-1.0 $(GTK_BASE)/include/glib-2.0
+ ifeq ($(TEC_SYSARCH), x64)
+ STDINCS += $(GTK_BASE)/lib64/glib-2.0/include $(GTK_BASE)/lib64/gtk-2.0/include
+ else
+ ifeq ($(TEC_SYSARCH), ia64)
+ STDINCS += $(GTK_BASE)/lib64/glib-2.0/include $(GTK_BASE)/lib64/gtk-2.0/include
+ else
+ STDINCS += $(GTK_BASE)/lib/glib-2.0/include $(GTK_BASE)/lib/gtk-2.0/include
+ endif
+ endif
+ ifneq ($(findstring FreeBSD, $(TEC_UNAME)), )
+ STDINCS += /lib/X11R6/include/gtk-2.0
+ endif
+# endif
+endif
+
+ifdef USE_QT
+ override USE_X11 = Yes
+ LIBS += QtGui QtCore
+ QT_BASE_INC := /usr/include/qt4
+ STDINCS += $(QT_BASE_INC) $(QT_BASE_INC)/QtCore $(QT_BASE_INC)/QtGui
+ STDDEFS += -DQT_DLL -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT
+endif
+
+ifdef USE_X11
+ LIBS += $(X11_LIBS)
+ LDIR += $(X11_LIB)
+ STDINCS += $(X11_INC)
+endif
+
+LIBS += m
+
+else
+ # gcc in Windows
+ NO_DYNAMIC ?= Yes
+ STDDEFS += -DWIN32
+
+ ifdef USE_NOCYGWIN
+ STDFLAGS += -mno-cygwin
+ endif
+
+ ifdef USE_GLUT
+ LIBS += glut32
+ endif
+
+ ifdef USE_OPENGL
+ LIBS += opengl32 glu32 glaux
+ endif
+
+ LIBS += gdi32 winspool comdlg32 comctl32 ole32
+
+ ifdef USE_GTK
+ LIBS += gtk-win32-2.0 gdk-win32-2.0 gdk_pixbuf-2.0 pango-1.0 pangowin32-1.0 gobject-2.0 gmodule-2.0 glib-2.0
+ #LDIR += $(GTK)/lib
+ GTK_INC = /usr
+ STDINCS += $(GTK_INC)/include/atk-1.0 $(GTK_INC)/include/gtk-2.0 $(GTK_INC)/include/cairo $(GTK_INC)/include/pango-1.0 $(GTK_INC)/include/glib-2.0 $(GTK_INC)/lib/glib-2.0/include $(GTK_INC)/lib/gtk-2.0/include
+ endif
+
+ APPTYPE ?= windows
+
+ ifeq ($(APPTYPE), windows)
+ LFLAGS += -mwindows
+
+ ifdef USE_NOCYGWIN
+ LFLAGS += -mno-cygwin
+ endif
+ endif
+endif
+
+
+#---------------------------------#
+# Building compilation flags that are sets
+
+INCLUDES := $(addprefix -I, $(INCLUDES))
+STDINCS := $(addprefix -I, $(STDINCS))
+EXTRAINCS := $(addprefix -I, $(EXTRAINCS))
+DEFINES := $(addprefix -D, $(DEFINES))
+
+LIBS := $(addprefix -l, $(LIBS))
+ifdef LDIR
+ LDIR := $(addprefix -L, $(LDIR))
+endif
+
+
+#---------------------------------#
+# Definitions of private variables
+
+# Library flags for application and dynamic library linker
+LFLAGS += $(LDIR) $(LIBS)
+# C compiler flags
+CFLAGS = $(FLAGS) $(STDFLAGS) $(INCLUDES) $(STDINCS) $(EXTRAINCS) $(DEFINES) $(STDDEFS)
+# C++ compiler flags
+CXXFLAGS = $(CPPFLAGS) $(STDFLAGS) $(INCLUDES) $(STDINCS) $(EXTRAINCS) $(DEFINES) $(STDDEFS)
+
+# Sources with relative path
+SOURCES := $(addprefix $(SRCDIR)/, $(SRC))
+
+# Target for applications or libraries
+ifeq ($(MAKETYPE), APP)
+ TARGET := $(TARGETDIR)/$(TARGETNAME)
+else
+ ifeq ($(NO_DYNAMIC), Yes)
+ TARGET := $(TARGETDIR)/lib$(TARGETNAME).a
+ else
+ TARGET := $(TARGETDIR)/lib$(TARGETNAME).a $(TARGETDIR)/lib$(TARGETNAME).$(DLIBEXT)
+ endif
+endif
+
+# OBJ: list of .o, without path
+# OBJS: list of .o with relative path
+OBJ = $(notdir $(SRC))
+OBJ := $(OBJ:.c=.o)
+OBJ := $(OBJ:.cpp=.o)
+OBJ := $(OBJ:.cxx=.o)
+OBJ := $(OBJ:.cc=.o)
+OBJ := $(OBJ:.f=.o)
+OBJ := $(OBJ:.for=.o)
+OBJ := $(OBJ:.rc=.ro)
+OBJS = $(addprefix $(OBJDIR)/, $(OBJ))
+
+# LOH: list of .loh, without path
+# LOHS: list of .loh, with relative path
+LO = $(notdir $(SRCLUA))
+LO := $(LO:.lua=$(LO_SUFFIX).lo)
+LOS = $(addprefix $(OBJROOT)/, $(LO))
+
+LOH = $(notdir $(SRCLUA))
+LOH := $(LOH:.lua=$(LO_SUFFIX).loh)
+LOHS = $(addprefix $(LOHDIR)/, $(LOH))
+
+# Construct VPATH variable
+P-SRC = $(dir $(SRC))
+P-SRC += $(dir $(SRCLUA))
+VPATH = .:$(foreach dir,$(P-SRC),$(if $(dir)="./",:$(dir)))
+
+
+#---------------------------------#
+# Main Rule - Build Everything that it is necessary
+
+.PHONY: tecmake
+ifeq ($(MAKETYPE), APP)
+ tecmake: print-start directories application scripts
+else
+ ifeq ($(NO_DYNAMIC), Yes)
+ tecmake: print-start directories static-lib
+ else
+ tecmake: print-start directories static-lib dynamic-lib
+ endif
+endif
+
+.PHONY: print-start
+print-start:
+ @echo ''; echo 'Tecmake - Starting [ $(TARGETNAME):$(TEC_UNAME) ]'
+
+
+#---------------------------------#
+# Dynamic Library Build
+
+.PHONY: dynamic-lib
+dynamic-lib: $(TARGETDIR)/lib$(TARGETNAME).$(DLIBEXT)
+
+$(TARGETDIR)/lib$(TARGETNAME).$(DLIBEXT) : $(LOHS) $(OBJS) $(EXTRADEPS)
+ $(LD) $(STDLDFLAGS) -o $@ $(OBJS) $(SLIB) $(LFLAGS)
+ @echo 'Tecmake - Dynamic Library ($@) Done.'; echo ''
+
+
+#---------------------------------#
+# Static Library Build
+
+.PHONY: static-lib
+static-lib: $(TARGETDIR)/lib$(TARGETNAME).a
+
+$(TARGETDIR)/lib$(TARGETNAME).a : $(LOHS) $(OBJS) $(EXTRADEPS)
+ $(AR) $(STDLFLAGS) $@ $(OBJS) $(SLIB) $(LCFLAGS)
+ -$(RANLIB) $@
+ @echo 'Tecmake - Static Library ($@) Done.'; echo ''
+
+
+#---------------------------------#
+# Application Build
+
+.PHONY: application
+application: $(TARGETDIR)/$(TARGETNAME)
+
+$(TARGETDIR)/$(TARGETNAME) : $(LOHS) $(OBJS) $(EXTRADEPS)
+ $(LINKER) -o $@ $(OBJS) $(SLIB) $(LFLAGS)
+ @if [ ! -z "$(STRIP)" ]; then \
+ echo "Striping debug information" ;\
+ strip $@ ;\
+ fi
+ @echo 'Tecmake - Application ($@) Done.'; echo ''
+
+
+#---------------------------------#
+# Application Scripts
+
+# Script name
+SRELEASE := $(SRCDIR)/$(TARGETNAME)
+
+.PHONY: scripts
+ifdef NO_SCRIPTS
+ scripts: ;
+else
+ scripts: $(SRELEASE) ;
+endif
+
+$(SRELEASE): $(MAKENAME)
+ @echo 'Building script $(@F)'
+ @echo "#!/bin/csh" > $@
+ @echo "# Script generated automatically by tecmake v$(VERSION)" >> $@
+ @echo "# Remove the comment bellow to set the LD_LIBRARY_PATH if needed." >> $@
+ @echo '#setenv LD_LIBRARY_PATH $(MYLIB1)/lib/$${TEC_UNAME}:$(MYLIB2)/lib/$${TEC_UNAME}:$$LD_LIBRARY_PATH' >> $@
+ @echo 'if ( -r app.env ) source app.env' >> $@
+ @echo 'exec $(TARGETROOT)/$$TEC_UNAME/$(TARGETNAME) $$*' >> $@
+ @chmod a+x $@
+
+
+#---------------------------------#
+# Directories Creation
+
+.PHONY: directories
+directories: $(OBJDIR) $(TARGETDIR) $(EXTRADIR) $(LOHDIR)
+
+$(OBJDIR) $(TARGETDIR):
+ if [ ! -d $@ ] ; then mkdir -p $@ ; fi
+
+ifdef EXTRADIR
+ $(EXTRADIR):
+ if [ ! -d $@ ] ; then mkdir -p $@ ; fi
+else
+ $(EXTRADIR): ;
+endif
+
+ifdef LOHDIR
+ $(LOHDIR):
+ if [ ! -d $@ ] ; then mkdir -p $@ ; fi
+else
+ $(LOHDIR): ;
+endif
+
+
+#---------------------------------#
+# Compilation Rules
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.c
+ @echo Compiling $(<F)...
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
+ @echo Compiling $(<F)...
+ $(CPPC) -c $(CXXFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.cxx
+ @echo Compiling $(<F)...
+ $(CPPC) -c $(CXXFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.cc
+ @echo Compiling $(<F)...
+ $(CPPC) -c $(CXXFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.f
+ @echo Compiling $(<F)...
+ $(FC) -c $(FFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.for
+ @echo Compiling $(<F)...
+ $(FC) -c $(FFLAGS) -o $@ $<
+
+$(OBJDIR)/%.ro: $(SRCDIR)/%.rc
+ @echo Compiling $(<F)...
+ $(RCC) $(RCFLAGS) -O coff -o $@ $<
+
+$(LOHDIR)/%.loh: $(OBJROOT)/%.lo
+ @echo Generating $(<F)...
+ $(BIN2C) $< > $@
+
+$(OBJROOT)/%$(LO_SUFFIX).lo: $(SRCLUADIR)/%.lua
+ @echo Compiling $(<F)...
+ $(LUAC) -o $@ $<
+
+
+#---------------------------------#
+# Dependencies
+
+# make depend
+# Build dependencies
+.PHONY: depend
+depend: $(DEPEND)
+
+$(DEPEND): $(MAKENAME)
+ ifdef SRC
+ @echo "" > $(DEPEND)
+ @which $(CPPC) 2> /dev/null 1>&2 ;\
+ if [ $$? -eq 0 ]; then \
+ echo "Building dependencies... (can be slow)" ;\
+ $(CPPC) $(INCLUDES) $(DEFINES) $(STDDEFS) -MM $(SOURCES) | \
+ sed -e '1,$$s/^\([^ ]\)/$$(OBJDIR)\/\1/' > $(DEPEND) ;\
+ else \
+ echo "" ;\
+ echo "$(CPPC) not found. Dependencies can not be built." ;\
+ echo "Must set USE_NODEPEND=Yes." ;\
+ echo "" ;\
+ exit 1 ;\
+ fi
+ endif
+
+###################
+ifndef USE_NODEPEND
+include $(DEPEND)
+endif
+###################
+
+
+#---------------------------------#
+# Management Rules
+
+# make clean-extra
+# Remove extra files
+.PHONY: clean-extra
+clean-extra:
+ rm -f $(DEPEND) $(SRELEASE) so_locations
+
+# make clean-lohs
+# Remove Lua object inclusion files
+.PHONY: clean-lohs
+clean-lohs:
+ rm -f $(LOS) $(LOHS)
+
+# make clean-obj
+# Remove object files
+.PHONY: clean-obj
+clean-obj:
+ rm -f $(OBJS)
+
+# make clean-target
+# Remove target
+.PHONY: clean-target
+clean-target:
+ rm -f $(TARGET)
+
+# make clean
+# Remove target and object files
+.PHONY: clean
+clean: clean-target clean-obj
+
+# make rebuild
+# Remove symbols from executables
+.PHONY: strip
+strip:
+ test -r $(TARGETDIR)/$(TARGETNAME) && strip $(TARGETDIR)/$(TARGETNAME)
+
+# make rebuild
+# Rebuild target and object files
+.PHONY: rebuild
+rebuild: clean-extra clean-lohs clean-obj clean-target tecmake
+
+# make relink
+# Rebuild target without rebuilding object files
+.PHONY: relink
+relink: clean-target tecmake
+
+.PHONY: version
+version:
+ @echo "Tecmake Compact Version $(VERSION)"
+
+#---------------------------------#